From bd214bc82d6effc48ced7e08ac2f70b3fdbe0c82 Mon Sep 17 00:00:00 2001 From: BlueMatthew Date: Sun, 26 Nov 2023 21:06:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HTDataStruct.h | 1 + include/HTGlobal.h | 22 +- include/HTIEC104.h | 1 - include/HTTcpSocket.h | 2 +- src/HTGlobal.cpp | 2 + src/HTIEC104.cpp | 5387 +++++++++++++++++++++------------------- src/HTService.cpp | 4 +- src/HTTcpSocket.cpp | 29 +- 8 files changed, 2877 insertions(+), 2571 deletions(-) diff --git a/include/HTDataStruct.h b/include/HTDataStruct.h index 7c7d0da..a92517c 100644 --- a/include/HTDataStruct.h +++ b/include/HTDataStruct.h @@ -118,6 +118,7 @@ typedef struct { typedef struct { + int sockid; int iLength ; // 接收长度 unsigned short usISUType; // 0,2=I ; 1=S ; 3=U unsigned short usSendNo; // 发送序号 diff --git a/include/HTGlobal.h b/include/HTGlobal.h index 9bb41d6..a8cb965 100644 --- a/include/HTGlobal.h +++ b/include/HTGlobal.h @@ -41,7 +41,7 @@ #include #include -#define _HT_OPENCV_APP // 图片分析处理程序 +// #define _HT_OPENCV_APP // 图片分析处理程序 #define _HT_IEC104_APP // IEC104通讯程序 #define _DEF_HMF_VOLTAGE // 黑麋峰高压侧电流计算 #define _DEF_DB_CHANGERATE // 启用偏差率入库功能,否则以设定的间隔时间入库 @@ -55,27 +55,29 @@ extern int g_Running; extern TConfig g_TConfig; extern TTcpSocket g_Tcp; -extern ST_IEC104_CTRL g_IecCtrl; // socket linker info and status -extern mutex g_IecCtrl_mutex; // socket linker on mutex +extern ST_IEC104_CTRL g_IecCtrl; // socket linker info and status +extern int g_MaxScokId; // socket linker info and status +extern std::map g_IecCtrls; +extern mutex g_IecCtrl_mutex; // socket linker on mutex extern map g_map_work; // 主变工作状态缓存 extern mutex g_map_work_mutex; // 主变工作状态缓存队列锁 -//extern map g_map_byq; // 变压器缓存数据 +//extern map g_map_byq; // 变压器缓存数据 extern map g_map_thres_byq; // 变压器缓存数据 extern mutex g_map_byq_mutex; // 变压器缓存数据信息队列锁 -//extern map g_map_gis; // GIS缓存数据 -//extern mutex g_map_gis_mutex; // GIS缓存数据信息队列锁 +//extern map g_map_gis; // GIS缓存数据 +//extern mutex g_map_gis_mutex; // GIS缓存数据信息队列锁 extern multimap g_map_relation; // 主设备与外挂设备关系 extern mutex g_map_relation_mutex; // GIS缓存数据信息队列锁 -//extern map g_map_gis_104; // GIS最近一次104上传数据缓存 -//extern mutex g_map_gis_104_mutex; +//extern map g_map_gis_104; // GIS最近一次104上传数据缓存 +//extern mutex g_map_gis_104_mutex; -//extern map g_map_blq; // BLQ缓存数据 -//extern mutex g_map_blq_mutex; // BLQ缓存数据信息队列锁 +//extern map g_map_blq; // BLQ缓存数据 +//extern mutex g_map_blq_mutex; // BLQ缓存数据信息队列锁 extern map g_map_iec; // 104报文解析缓存数据 extern mutex g_map_iec_mutex; // 104报文解析缓存数据信息队列锁 diff --git a/include/HTIEC104.h b/include/HTIEC104.h index 33d1f4b..c437a32 100644 --- a/include/HTIEC104.h +++ b/include/HTIEC104.h @@ -55,7 +55,6 @@ protected: }; void IEC104EnvFree(); void IEC104EnvLoad(); -void UpdateLastTime(); void *thread_listen_proc(void *arg); void *thread_client_proc(void *arg); diff --git a/include/HTTcpSocket.h b/include/HTTcpSocket.h index edb8e0b..29147ff 100644 --- a/include/HTTcpSocket.h +++ b/include/HTTcpSocket.h @@ -50,7 +50,7 @@ static const int MAX_SBUFF_TCP = 2048; //发送最大包长度 #define ErrException -1022 /* socket exceptions close */ -class TTcpSocket +class TTcpSocket { public: void clear_tcp_buffer(int socket_fd, int nbytes); diff --git a/src/HTGlobal.cpp b/src/HTGlobal.cpp index f3437f9..5866eb0 100644 --- a/src/HTGlobal.cpp +++ b/src/HTGlobal.cpp @@ -19,6 +19,8 @@ TTcpSocket g_Tcp; int g_Running; ST_IEC104_CTRL g_IecCtrl; // socket linker info and status +std::map g_IecCtrls; +int g_MaxScokId; // socket linker info and status mutex g_IecCtrl_mutex; // socket linker on mutex int g_seqno; // 与MEC之间交换的流水号 diff --git a/src/HTIEC104.cpp b/src/HTIEC104.cpp index 8a51de7..1b067e1 100644 --- a/src/HTIEC104.cpp +++ b/src/HTIEC104.cpp @@ -13,6 +13,9 @@ //#include #include "HTGlobal.h" #include "HTIEC104.h" +#ifndef _WIN32 +#include +#endif static const char *_FILE_ = "HTIEC104.cpp"; static FILE *fpIec = NULL; // iec104 config file handle. @@ -42,6 +45,9 @@ mutex g_list_warn_mutex; mutex g_sendno_mutex; +void DecodeMsgFormatU(ST_IEC104_CTRL* pIecCtrl, ST_APCI *p); +int DecodeMsgFormatI(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len, unsigned short sendno); + CIEC104::CIEC104() { } @@ -50,19 +56,19 @@ CIEC104::~CIEC104() } static void vPrtListCount() { - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pack count:%d", g_list_pack.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_dbset count:%d", g_list_dbset.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_origin count:%d", g_list_origin.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pingce count:%d", g_list_pingce.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_warn count:%d", g_list_warn.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pack count:%d", g_list_pack.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_dbset count:%d", g_list_dbset.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_origin count:%d", g_list_origin.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pingce count:%d", g_list_pingce.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_warn count:%d", g_list_warn.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_thres_byq count:%d", g_map_thres_byq.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_relation count:%d", g_map_relation.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_thres_byq count:%d", g_map_thres_byq.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_relation count:%d", g_map_relation.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_iec count:%d", g_map_iec.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_img_thres count:%d", g_map_img_thres.size()); - vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_iec count:%d", g_map_iec.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_img_thres count:%d", g_map_img_thres.size()); + vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size()); } /************************************************************************* @@ -82,173 +88,173 @@ Return Code : *************************************************************************/ static int iGetString(const char *pszSection, const char *pszEntry, char *pszRetBuf, unsigned int uiBufLen) { - //FILE *fpIni; - char szBuf[DEF_BUFFER_1K + 1], *psz1, *psz2, *psz; - int iSectFlag, iLen; - - if (fpIec == NULL) { - if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL) - return (-1); - } - fseek(fpIec, 0, SEEK_SET); - /*** check section ***/ - iSectFlag = 0; - while (!feof(fpIec)) { - if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break; - psz = szBuf; - - while (*psz != '[' && *psz != '#' && *psz != '\0') psz++; - if (*psz != '[') continue; - psz++; - while (*psz == ' ' || *psz == '\t') psz++; - psz1 = psz; - while (*psz != ']' && *psz != '\0') psz++; - if (*psz == '\0') continue; - while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--; - *psz = '\0'; - if (!strcmp(psz1, pszSection)) { - iSectFlag = 1; - break; - } - }/*** while ***/ - if (!iSectFlag) { - //fclose(fpIni); - return (-1); - } - - /*** check entry ***/ - while (!feof(fpIec)) { - if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break; - psz = szBuf; - while (*psz == ' ' || *psz == '\t') psz++; - if (*psz == '#' || *psz == '\0') continue; - if (*psz == '[') break; - - psz1 = psz; - while (*psz != '=' && *psz != '\0') psz++; - if (*psz == '\0') continue; - psz2 = psz + 1; - if (psz1 == psz) continue; - while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--; - *psz = '\0'; + //FILE *fpIni; + char szBuf[DEF_BUFFER_1K + 1], *psz1, *psz2, *psz; + int iSectFlag, iLen; + + if (fpIec == NULL) { + if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL) + return (-1); + } + fseek(fpIec, 0, SEEK_SET); + /*** check section ***/ + iSectFlag = 0; + while (!feof(fpIec)) { + if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break; + psz = szBuf; + + while (*psz != '[' && *psz != '#' && *psz != '\0') psz++; + if (*psz != '[') continue; + psz++; + while (*psz == ' ' || *psz == '\t') psz++; + psz1 = psz; + while (*psz != ']' && *psz != '\0') psz++; + if (*psz == '\0') continue; + while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--; + *psz = '\0'; + if (!strcmp(psz1, pszSection)) { + iSectFlag = 1; + break; + } + }/*** while ***/ + if (!iSectFlag) { + //fclose(fpIni); + return (-1); + } + + /*** check entry ***/ + while (!feof(fpIec)) { + if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break; + psz = szBuf; + while (*psz == ' ' || *psz == '\t') psz++; + if (*psz == '#' || *psz == '\0') continue; + if (*psz == '[') break; + + psz1 = psz; + while (*psz != '=' && *psz != '\0') psz++; + if (*psz == '\0') continue; + psz2 = psz + 1; + if (psz1 == psz) continue; + while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--; + *psz = '\0'; #ifdef _WIN32 - if (strcmp(psz1, pszEntry)) continue; + if (strcmp(psz1, pszEntry)) continue; #else - if (strcasecmp(psz1, pszEntry)) continue; + if (strcasecmp(psz1, pszEntry)) continue; #endif - //fclose(fpIni); - - psz = psz2; - while (*psz == ' ' || *psz == '\t') psz++; - psz2 = psz; - while (*psz != '#' && *psz != '\0' && !(*psz == '/' && (*(psz + 1) == '*' || *(psz + 1) == '/'))) psz++; - while (*(psz - 1) == ' ' || *(psz - 1) == '\t' || *(psz - 1) == 0x0a || *(psz - 1) == 0x0d) - { - *(psz - 1) = '\0'; - psz--; - } - //*psz= '\0'; - iLen = strlen(psz2); - if (psz2[iLen - 1] == 0x0a || psz2[iLen - 1] == 0x0d) psz2[iLen - 1] = 0x00; - if (iLen == 0) return (0); //return (-1); // 参数未设置,即参数值为空的情况 - if (iLen > (int)uiBufLen) iLen = uiBufLen; - memcpy(pszRetBuf, psz2, iLen); - *(pszRetBuf + iLen) = '\0'; - return (0); - } - //fclose(fpIni); - return (-1); + //fclose(fpIni); + + psz = psz2; + while (*psz == ' ' || *psz == '\t') psz++; + psz2 = psz; + while (*psz != '#' && *psz != '\0' && !(*psz == '/' && (*(psz + 1) == '*' || *(psz + 1) == '/'))) psz++; + while (*(psz - 1) == ' ' || *(psz - 1) == '\t' || *(psz - 1) == 0x0a || *(psz - 1) == 0x0d) + { + *(psz - 1) = '\0'; + psz--; + } + //*psz= '\0'; + iLen = strlen(psz2); + if (psz2[iLen - 1] == 0x0a || psz2[iLen - 1] == 0x0d) psz2[iLen - 1] = 0x00; + if (iLen == 0) return (0); //return (-1); // 参数未设置,即参数值为空的情况 + if (iLen > (int)uiBufLen) iLen = uiBufLen; + memcpy(pszRetBuf, psz2, iLen); + *(pszRetBuf + iLen) = '\0'; + return (0); + } + //fclose(fpIni); + return (-1); } static void setSadrMatchRelations(unsigned int key, ST_SADR_MATCH *pstAdr) { - ST_SADR_MATCH stAdr; - memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); - - if (key <= 0) return; // key=0时,表示104配置文件中无此点表地址、地址为空的情况 - stAdr.eqm_type = pstAdr->eqm_type; - stAdr.count = pstAdr->count; - - stAdr.psadr = (ST_MATCH_LIST*)calloc(pstAdr->count, sizeof(ST_MATCH_LIST)); - memcpy(stAdr.psadr, pstAdr->psadr, (pstAdr->count * sizeof(ST_MATCH_LIST))); - - mutex_lock(g_map_sadr_mutex); - g_map_sadr.insert(map::value_type(key, stAdr)); - mutex_unlock(g_map_sadr_mutex); + ST_SADR_MATCH stAdr; + memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); + + if (key <= 0) return; // key=0时,表示104配置文件中无此点表地址、地址为空的情况 + stAdr.eqm_type = pstAdr->eqm_type; + stAdr.count = pstAdr->count; + + stAdr.psadr = (ST_MATCH_LIST*)calloc(pstAdr->count, sizeof(ST_MATCH_LIST)); + memcpy(stAdr.psadr, pstAdr->psadr, (pstAdr->count * sizeof(ST_MATCH_LIST))); + + mutex_lock(g_map_sadr_mutex); + g_map_sadr.insert(map::value_type(key, stAdr)); + mutex_unlock(g_map_sadr_mutex); } // 加IEC104业务配置文件数据 static bool iGetIEC104Conf() { - int iRet = -1, i; - char szTmp[512], szSection[128]; + int iRet = -1, i; + char szTmp[512], szSection[128]; - memset(&g_iec_conf, 0x00, sizeof(ST_IEC104_CONF)); // 初始化IEC104配置. + memset(&g_iec_conf, 0x00, sizeof(ST_IEC104_CONF)); // 初始化IEC104配置. g_iec_conf.orgin_data_save_internal = 3600; - // 打开配置文件,准备加载配置参数 - if (fpIec == NULL) { - if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL) { - vPrtLogMsg(LOG_ERROR, errno, "open config file: %s failed!", HT_CONFIMG_FILE); - return NULL; - } - } - - // 获取变压器配置项的个数 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_DEVCOUNT", "iec_byq_count", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get iec_byq_count parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.iec_byq_count = (unsigned int)atoi(szTmp); - // 申请变压器设备编码缓冲区 - g_iec_conf.pstByqCode = (ST_BYQ_EQM_CODE*)calloc(g_iec_conf.iec_byq_count, sizeof(ST_BYQ_EQM_CODE)); - if (!g_iec_conf.pstByqCode) { - vPrtLogMsg(LOG_ERROR, iRet, "calloc byq_eqm_code cache size: %d failed!", g_iec_conf.iec_byq_count * sizeof(ST_BYQ_EQM_CODE)); - fclose(fpIec); - return false; - } - - // 获取断路器配置项的个数 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_DEVCOUNT", "iec_break_count", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get iec_break_count parameter failed!"); - // fclose(fpIec); - // return false; - g_iec_conf.iec_break_count = 0; - } - else - { - g_iec_conf.iec_break_count = (unsigned int)atoi(szTmp); - } - // 申请断路器设备编码缓冲区 - g_iec_conf.pstBrkCode = (ST_BREAK_EQM_CODE*)calloc(g_iec_conf.iec_break_count, sizeof(ST_BREAK_EQM_CODE)); - if (!g_iec_conf.pstBrkCode) { - vPrtLogMsg(LOG_ERROR, iRet, "calloc brk_eqm_code cache size: %d failed!", g_iec_conf.iec_break_count * sizeof(ST_BREAK_EQM_CODE)); - fclose(fpIec); - return false; - } - // 获取站点ID配置项 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_DEVCOUNT", "iec_site_id", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get iec_site_id parameter failed!"); - fclose(fpIec); - return false; - } - strcpy((char*)g_iec_conf.site_id , szTmp); - - vPrtLogMsg(LOG_DEBUG, 0, "get iec_byq_count config count: byq_cnt:%d,gis_cnt:%d,site_id:%s", - g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count, szTmp); - - // 104时间保存间隔时间(s) - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("COMM_SAVE_INTERNAL", "DATA_SAVE_INTERNAL", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get DATA_SAVE_INTERNAL parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.save_internal = (unsigned int)atoi(szTmp); + // 打开配置文件,准备加载配置参数 + if (fpIec == NULL) { + if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL) { + vPrtLogMsg(LOG_ERROR, errno, "open config file: %s failed!", HT_CONFIMG_FILE); + return NULL; + } + } + + // 获取变压器配置项的个数 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_DEVCOUNT", "iec_byq_count", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get iec_byq_count parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.iec_byq_count = (unsigned int)atoi(szTmp); + // 申请变压器设备编码缓冲区 + g_iec_conf.pstByqCode = (ST_BYQ_EQM_CODE*)calloc(g_iec_conf.iec_byq_count, sizeof(ST_BYQ_EQM_CODE)); + if (!g_iec_conf.pstByqCode) { + vPrtLogMsg(LOG_ERROR, iRet, "calloc byq_eqm_code cache size: %d failed!", g_iec_conf.iec_byq_count * sizeof(ST_BYQ_EQM_CODE)); + fclose(fpIec); + return false; + } + + // 获取断路器配置项的个数 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_DEVCOUNT", "iec_break_count", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get iec_break_count parameter failed!"); + // fclose(fpIec); + // return false; + g_iec_conf.iec_break_count = 0; + } + else + { + g_iec_conf.iec_break_count = (unsigned int)atoi(szTmp); + } + // 申请断路器设备编码缓冲区 + g_iec_conf.pstBrkCode = (ST_BREAK_EQM_CODE*)calloc(g_iec_conf.iec_break_count, sizeof(ST_BREAK_EQM_CODE)); + if (!g_iec_conf.pstBrkCode) { + vPrtLogMsg(LOG_ERROR, iRet, "calloc brk_eqm_code cache size: %d failed!", g_iec_conf.iec_break_count * sizeof(ST_BREAK_EQM_CODE)); + fclose(fpIec); + return false; + } + // 获取站点ID配置项 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_DEVCOUNT", "iec_site_id", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get iec_site_id parameter failed!"); + fclose(fpIec); + return false; + } + strcpy((char*)g_iec_conf.site_id, szTmp); + + vPrtLogMsg(LOG_DEBUG, 0, "get iec_byq_count config count: byq_cnt:%d,gis_cnt:%d,site_id:%s", + g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count, szTmp); + + // 104时间保存间隔时间(s) + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("COMM_SAVE_INTERNAL", "DATA_SAVE_INTERNAL", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get DATA_SAVE_INTERNAL parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.save_internal = (unsigned int)atoi(szTmp); // 总召间隔时间(s) memset(szTmp, 0x00, sizeof(szTmp)); @@ -268,512 +274,553 @@ static bool iGetIEC104Conf() } g_iec_conf.orgin_data_save_internal = (unsigned int)atoi(szTmp); - // 获取公共地址配置 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "iec_global_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get iec_global_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.iec_global_addr = (unsigned short)atoi(szTmp); - - // 获取YC地址配置 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_start_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get yx_start_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.yx_start_addr = (unsigned int)atoi(szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_stop_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get yx_stop_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.yx_stop_addr = (unsigned int)atoi(szTmp); - - // 获取JB地址配置 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_start_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get jb_start_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.jb_start_addr = (unsigned int)atoi(szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_stop_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get jb_stop_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.jb_stop_addr = (unsigned int)atoi(szTmp); - - // 获取YC地址配置 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_start_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get yc_start_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.yc_start_addr = (unsigned int)atoi(szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_stop_addr", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get yc_stop_addr parameter failed!"); - fclose(fpIec); - return false; - } - g_iec_conf.yc_stop_addr = (unsigned int)atoi(szTmp); - - - // 获取BYQ配置各项参数 - for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - { - snprintf(szSection, sizeof(szSection), "IEC_BYQ_CODE_%02d", i + 1); - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "EQM_CODE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE parameter failed", szSection); - fclose(fpIec); - return false; - } - strcpy((char*)g_iec_conf.pstByqCode[i].szEqmCode, szTmp); - - // 主变高压侧电压、电流点位HIGH_VOLTAGE, HIGH_CURRENT = 16387 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "HIGH_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_VOLTAGE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiHighVoltage = atoi(szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "HIGH_CURRENT", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_CURRENT parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiHighCurrent = atoi(szTmp); - - - //主变低压(出口)侧电压、电流点位 LOW_VOLTAGE = 16700 LOW_CURRENT = 16701 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "LOW_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_VOLTAGE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiLowVoltage = atoi(szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "LOW_CURRENT", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_CURRENT parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiLowCurrent = atoi(szTmp); - - - //# 运行工况点位 - //# 主变冷却水进口压力点位 COOL_WATER_PRESS_ENTRY = 16365 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_ENTRY parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry = atoi(szTmp); - - //# 主变冷却水出口压力点位 COOL_WATER_PRESS_OUTER = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_OUTER parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter = atoi(szTmp); - - //# 主变冷却水进口温度点位 COOL_WATER_TEMP_ENTRY = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_ENTRY parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry = atoi(szTmp); - - //# 主变冷却水出口温度点位 COOL_WATER_TEMP_OUTER = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_OUTER parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter = atoi(szTmp); - - - //# 主变油进口压力点位 OIL_PRESS_ENTRY = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_ENTRY parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilPressEntry = atoi(szTmp); - - //# 主变油出口压力点位 OIL_PRESS_OUTER = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_OUTER parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilPressOuter = atoi(szTmp); - - - //# 主变油进口温度点位 OIL_TEMP_ENTRY = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_ENTRY parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilTempEntry = atoi(szTmp); - - //# 主变油出口温度点位 OIL_TEMP_OUTER = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_OUTER parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilTempOuter = atoi(szTmp); - - //# 主变绕组温度点位 WINDING_TEMPERATURE = 16366 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "WINDING_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: WINDING_TEMPERATURE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiWindingTemp = atoi(szTmp); - - - //# 主变油温点位 OIL_TEMPERATURE = 16405 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMPERATURE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilTemperature = atoi(szTmp); - - //# 主变顶层油温点位 OIL_TOP_TEMPERATURE = 16405 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_TOP_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TOP_TEMPERATURE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilTopTemp = atoi(szTmp); - - //# 主变油位点位 OIL_POSITION = 16406 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_POSITION", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_POSITION parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilPosition = atoi(szTmp); - - //# 主变油枕油位点位 OIL_OILPILLOW_OILLEVEL = 16406 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "OIL_OILPILLOW_OILLEVEL", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_OILPILLOW_OILLEVEL parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstByqCode[i].uiOilPillowLevel = atoi(szTmp); - } - - // 获取断路器配置各项参数 - for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) - { - ST_BREAK_EQM_CODE stGisState; - - memset(&stGisState, 0x00, sizeof(ST_BREAK_EQM_CODE)); - - snprintf(szSection, sizeof(szSection), "IEC_BREAK_CODE_%02d", i + 1); - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "EQM_CODE_A", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_A parameter failed", szSection); - fclose(fpIec); - return false; - } - strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeA, szTmp); - strcpy((char*)stGisState.szEqmCodeA, szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "EQM_CODE_B", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_B parameter failed", szSection); - fclose(fpIec); - return false; - } - strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeB, szTmp); - strcpy((char*)stGisState.szEqmCodeB, szTmp); - - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "EQM_CODE_C", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_C parameter failed", szSection); - fclose(fpIec); - return false; - } - strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeC, szTmp); - strcpy((char*)stGisState.szEqmCodeC, szTmp); - - // 断开状态点位,开关的遥信点位 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "STATE_SIGNAL", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: STATE_SIGNAL parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstBrkCode[i].uiStateSadr = atoi(szTmp); - stGisState.uiStateSadr = atoi(szTmp); - - // 断开电压点位 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "ABORT_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_VOLTAGE parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstBrkCode[i].uiAbortVoltage = atoi(szTmp); - stGisState.uiAbortVoltage = atoi(szTmp); - - // 断开电流点位 - memset(szTmp, 0x00, sizeof(szTmp)); - if ((iRet = iGetString(szSection, "ABORT_CURRENT", szTmp, sizeof(szTmp))) < 0) { - vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_CURRENT parameter failed", szSection); - fclose(fpIec); - return false; - } - g_iec_conf.pstBrkCode[i].uiAbortCurrent = atoi(szTmp); - stGisState.uiAbortCurrent = atoi(szTmp); - - mutex_lock(g_map_gis_state_mutex); // 断路器遥信状态下,对应其电流电压点位 - g_map_gis_state.insert(map::value_type(stGisState.uiStateSadr, stGisState)); - mutex_unlock(g_map_gis_state_mutex); - } - fclose(fpIec); - - // 根据配置,建立点表地址匹配关系map - for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - { - // 主变高压侧电流电压匹配关系 - ST_SADR_MATCH stAdr; - memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); - stAdr.eqm_type = 1; - stAdr.count = 2; - stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); - stAdr.psadr[0].group = 1; // 高压侧电流、电压组 - stAdr.psadr[0].btype = 1; // 高压侧电流 - stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; - - stAdr.psadr[1].group = 1; // 高压侧电流、电压组 - stAdr.psadr[1].btype = 2; // 高压侧电压 - stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiHighVoltage; - - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighVoltage, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighCurrent, &stAdr); - if (stAdr.psadr) free(stAdr.psadr); - stAdr.psadr = NULL; - - // 主变低压侧电流电压匹配关系 - stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); - stAdr.psadr[0].group = 2; // 低压侧电流、电压组 - stAdr.psadr[0].btype = 1; //低压侧电流 - stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; - - stAdr.psadr[1].group = 2; // 低压侧电流、电压组 - stAdr.psadr[1].btype = 2; //低压侧电压 - stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiLowVoltage; - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowVoltage, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowCurrent, &stAdr); - if (stAdr.psadr) free(stAdr.psadr); - stAdr.psadr = NULL; - - // 运行工况 - stAdr.eqm_type = 1; - stAdr.count = 13; - stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); - stAdr.psadr[0].group = 3; // 运行工况组 - stAdr.psadr[0].btype = 1; // 进口水压力 - stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry; - - stAdr.psadr[1].group = 3; // 运行工况组 - stAdr.psadr[1].btype = 2; // 出口水压力 - stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter; - - stAdr.psadr[2].group = 3; // 运行工况组 - stAdr.psadr[2].btype = 3; // 主变本体油位数 - stAdr.psadr[2].sadr = g_iec_conf.pstByqCode[i].uiOilPosition; - - stAdr.psadr[3].group = 3; // 运行工况组 - stAdr.psadr[3].btype = 4; // 主变本体油温数 - stAdr.psadr[3].sadr = g_iec_conf.pstByqCode[i].uiOilTemperature; - - stAdr.psadr[4].group = 3; // 运行工况组 - stAdr.psadr[4].btype = 5; // 进口水温度 - stAdr.psadr[4].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry; - - stAdr.psadr[5].group = 3; // 运行工况组 - stAdr.psadr[5].btype = 6; // 出口水温度 - stAdr.psadr[5].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter; - - stAdr.psadr[6].group = 3; // 运行工况组 - stAdr.psadr[6].btype = 7; // 进口油压力 - stAdr.psadr[6].sadr = g_iec_conf.pstByqCode[i].uiOilPressEntry; - - stAdr.psadr[7].group = 3; // 运行工况组 - stAdr.psadr[7].btype = 8; // 出口油压力 - stAdr.psadr[7].sadr = g_iec_conf.pstByqCode[i].uiOilPressOuter; - - stAdr.psadr[8].group = 3; // 运行工况组 - stAdr.psadr[8].btype = 9; // 进口油温度 - stAdr.psadr[8].sadr = g_iec_conf.pstByqCode[i].uiOilTempEntry; - - stAdr.psadr[9].group = 3; // 运行工况组 - stAdr.psadr[9].btype = 10; // 出口油温度 - stAdr.psadr[9].sadr = g_iec_conf.pstByqCode[i].uiOilTempOuter; - - stAdr.psadr[10].group = 3; // 运行工况组 - stAdr.psadr[10].btype = 11; // 油枕油位 - stAdr.psadr[10].sadr = g_iec_conf.pstByqCode[i].uiOilPillowLevel; - - stAdr.psadr[11].group = 3; // 运行工况组 - stAdr.psadr[11].btype = 12; // 顶层油温度 - stAdr.psadr[11].sadr = g_iec_conf.pstByqCode[i].uiOilTopTemp; - - stAdr.psadr[12].group = 3; // 运行工况组 - stAdr.psadr[12].btype = 13; // 绕组温度 - stAdr.psadr[12].sadr = g_iec_conf.pstByqCode[i].uiWindingTemp; - - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPosition, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTemperature, &stAdr); - - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressEntry, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressOuter, &stAdr); - - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempEntry, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempOuter, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPillowLevel, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTopTemp, &stAdr); - setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiWindingTemp, &stAdr); - if (stAdr.psadr) free(stAdr.psadr); - stAdr.psadr = NULL; - } - for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) - { - ST_SADR_MATCH stAdr; - memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); - stAdr.eqm_type = 2; - stAdr.count = 2; - stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); - - stAdr.psadr[0].group = 4; - stAdr.psadr[0].btype = 1; // 断开电流 - stAdr.psadr[0].sadr = g_iec_conf.pstBrkCode[i].uiAbortCurrent; - - stAdr.psadr[1].group = 4; - stAdr.psadr[1].btype = 2; // 断开电压 - stAdr.psadr[1].sadr = g_iec_conf.pstBrkCode[i].uiAbortVoltage; - setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortVoltage, &stAdr); - setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortCurrent, &stAdr); - if (stAdr.psadr) free(stAdr.psadr); - stAdr.psadr = NULL; - } - return true; + // 获取公共地址配置 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "iec_global_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get iec_global_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.iec_global_addr = (unsigned short)atoi(szTmp); + + // 获取YC地址配置 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_start_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get yx_start_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.yx_start_addr = (unsigned int)atoi(szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_stop_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get yx_stop_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.yx_stop_addr = (unsigned int)atoi(szTmp); + + // 获取JB地址配置 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_start_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get jb_start_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.jb_start_addr = (unsigned int)atoi(szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_stop_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get jb_stop_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.jb_stop_addr = (unsigned int)atoi(szTmp); + + // 获取YC地址配置 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_start_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get yc_start_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.yc_start_addr = (unsigned int)atoi(szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_stop_addr", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get yc_stop_addr parameter failed!"); + fclose(fpIec); + return false; + } + g_iec_conf.yc_stop_addr = (unsigned int)atoi(szTmp); + + + // 获取BYQ配置各项参数 + for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + { + snprintf(szSection, sizeof(szSection), "IEC_BYQ_CODE_%02d", i + 1); + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "EQM_CODE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE parameter failed", szSection); + fclose(fpIec); + return false; + } + strcpy((char*)g_iec_conf.pstByqCode[i].szEqmCode, szTmp); + + // 主变高压侧电压、电流点位HIGH_VOLTAGE, HIGH_CURRENT = 16387 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "HIGH_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_VOLTAGE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiHighVoltage = atoi(szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "HIGH_CURRENT", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_CURRENT parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiHighCurrent = atoi(szTmp); + + + //主变低压(出口)侧电压、电流点位 LOW_VOLTAGE = 16700 LOW_CURRENT = 16701 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "LOW_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_VOLTAGE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiLowVoltage = atoi(szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "LOW_CURRENT", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_CURRENT parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiLowCurrent = atoi(szTmp); + + + //# 运行工况点位 + //# 主变冷却水进口压力点位 COOL_WATER_PRESS_ENTRY = 16365 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_ENTRY parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry = atoi(szTmp); + + //# 主变冷却水出口压力点位 COOL_WATER_PRESS_OUTER = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_OUTER parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter = atoi(szTmp); + + //# 主变冷却水进口温度点位 COOL_WATER_TEMP_ENTRY = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_ENTRY parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry = atoi(szTmp); + + //# 主变冷却水出口温度点位 COOL_WATER_TEMP_OUTER = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_OUTER parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter = atoi(szTmp); + + + //# 主变油进口压力点位 OIL_PRESS_ENTRY = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_ENTRY parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilPressEntry = atoi(szTmp); + + //# 主变油出口压力点位 OIL_PRESS_OUTER = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_OUTER parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilPressOuter = atoi(szTmp); + + + //# 主变油进口温度点位 OIL_TEMP_ENTRY = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_ENTRY parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilTempEntry = atoi(szTmp); + + //# 主变油出口温度点位 OIL_TEMP_OUTER = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_OUTER parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilTempOuter = atoi(szTmp); + + //# 主变绕组温度点位 WINDING_TEMPERATURE = 16366 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "WINDING_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: WINDING_TEMPERATURE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiWindingTemp = atoi(szTmp); + + + //# 主变油温点位 OIL_TEMPERATURE = 16405 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMPERATURE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilTemperature = atoi(szTmp); + + //# 主变顶层油温点位 OIL_TOP_TEMPERATURE = 16405 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_TOP_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TOP_TEMPERATURE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilTopTemp = atoi(szTmp); + + //# 主变油位点位 OIL_POSITION = 16406 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_POSITION", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_POSITION parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilPosition = atoi(szTmp); + + //# 主变油枕油位点位 OIL_OILPILLOW_OILLEVEL = 16406 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "OIL_OILPILLOW_OILLEVEL", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_OILPILLOW_OILLEVEL parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstByqCode[i].uiOilPillowLevel = atoi(szTmp); + } + + // 获取断路器配置各项参数 + for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) + { + ST_BREAK_EQM_CODE stGisState; + + memset(&stGisState, 0x00, sizeof(ST_BREAK_EQM_CODE)); + + snprintf(szSection, sizeof(szSection), "IEC_BREAK_CODE_%02d", i + 1); + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "EQM_CODE_A", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_A parameter failed", szSection); + fclose(fpIec); + return false; + } + strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeA, szTmp); + strcpy((char*)stGisState.szEqmCodeA, szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "EQM_CODE_B", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_B parameter failed", szSection); + fclose(fpIec); + return false; + } + strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeB, szTmp); + strcpy((char*)stGisState.szEqmCodeB, szTmp); + + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "EQM_CODE_C", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_C parameter failed", szSection); + fclose(fpIec); + return false; + } + strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeC, szTmp); + strcpy((char*)stGisState.szEqmCodeC, szTmp); + + // 断开状态点位,开关的遥信点位 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "STATE_SIGNAL", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: STATE_SIGNAL parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstBrkCode[i].uiStateSadr = atoi(szTmp); + stGisState.uiStateSadr = atoi(szTmp); + + // 断开电压点位 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "ABORT_VOLTAGE", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_VOLTAGE parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstBrkCode[i].uiAbortVoltage = atoi(szTmp); + stGisState.uiAbortVoltage = atoi(szTmp); + + // 断开电流点位 + memset(szTmp, 0x00, sizeof(szTmp)); + if ((iRet = iGetString(szSection, "ABORT_CURRENT", szTmp, sizeof(szTmp))) < 0) { + vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_CURRENT parameter failed", szSection); + fclose(fpIec); + return false; + } + g_iec_conf.pstBrkCode[i].uiAbortCurrent = atoi(szTmp); + stGisState.uiAbortCurrent = atoi(szTmp); + + mutex_lock(g_map_gis_state_mutex); // 断路器遥信状态下,对应其电流电压点位 + g_map_gis_state.insert(map::value_type(stGisState.uiStateSadr, stGisState)); + mutex_unlock(g_map_gis_state_mutex); + } + fclose(fpIec); + + // 根据配置,建立点表地址匹配关系map + for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + { + // 主变高压侧电流电压匹配关系 + ST_SADR_MATCH stAdr; + memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); + stAdr.eqm_type = 1; + stAdr.count = 2; + stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); + stAdr.psadr[0].group = 1; // 高压侧电流、电压组 + stAdr.psadr[0].btype = 1; // 高压侧电流 + stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; + + stAdr.psadr[1].group = 1; // 高压侧电流、电压组 + stAdr.psadr[1].btype = 2; // 高压侧电压 + stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiHighVoltage; + + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighVoltage, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighCurrent, &stAdr); + if (stAdr.psadr) free(stAdr.psadr); + stAdr.psadr = NULL; + + // 主变低压侧电流电压匹配关系 + stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); + stAdr.psadr[0].group = 2; // 低压侧电流、电压组 + stAdr.psadr[0].btype = 1; //低压侧电流 + stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; + + stAdr.psadr[1].group = 2; // 低压侧电流、电压组 + stAdr.psadr[1].btype = 2; //低压侧电压 + stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiLowVoltage; + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowVoltage, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowCurrent, &stAdr); + if (stAdr.psadr) free(stAdr.psadr); + stAdr.psadr = NULL; + + // 运行工况 + stAdr.eqm_type = 1; + stAdr.count = 13; + stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); + stAdr.psadr[0].group = 3; // 运行工况组 + stAdr.psadr[0].btype = 1; // 进口水压力 + stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry; + + stAdr.psadr[1].group = 3; // 运行工况组 + stAdr.psadr[1].btype = 2; // 出口水压力 + stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter; + + stAdr.psadr[2].group = 3; // 运行工况组 + stAdr.psadr[2].btype = 3; // 主变本体油位数 + stAdr.psadr[2].sadr = g_iec_conf.pstByqCode[i].uiOilPosition; + + stAdr.psadr[3].group = 3; // 运行工况组 + stAdr.psadr[3].btype = 4; // 主变本体油温数 + stAdr.psadr[3].sadr = g_iec_conf.pstByqCode[i].uiOilTemperature; + + stAdr.psadr[4].group = 3; // 运行工况组 + stAdr.psadr[4].btype = 5; // 进口水温度 + stAdr.psadr[4].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry; + + stAdr.psadr[5].group = 3; // 运行工况组 + stAdr.psadr[5].btype = 6; // 出口水温度 + stAdr.psadr[5].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter; + + stAdr.psadr[6].group = 3; // 运行工况组 + stAdr.psadr[6].btype = 7; // 进口油压力 + stAdr.psadr[6].sadr = g_iec_conf.pstByqCode[i].uiOilPressEntry; + + stAdr.psadr[7].group = 3; // 运行工况组 + stAdr.psadr[7].btype = 8; // 出口油压力 + stAdr.psadr[7].sadr = g_iec_conf.pstByqCode[i].uiOilPressOuter; + + stAdr.psadr[8].group = 3; // 运行工况组 + stAdr.psadr[8].btype = 9; // 进口油温度 + stAdr.psadr[8].sadr = g_iec_conf.pstByqCode[i].uiOilTempEntry; + + stAdr.psadr[9].group = 3; // 运行工况组 + stAdr.psadr[9].btype = 10; // 出口油温度 + stAdr.psadr[9].sadr = g_iec_conf.pstByqCode[i].uiOilTempOuter; + + stAdr.psadr[10].group = 3; // 运行工况组 + stAdr.psadr[10].btype = 11; // 油枕油位 + stAdr.psadr[10].sadr = g_iec_conf.pstByqCode[i].uiOilPillowLevel; + + stAdr.psadr[11].group = 3; // 运行工况组 + stAdr.psadr[11].btype = 12; // 顶层油温度 + stAdr.psadr[11].sadr = g_iec_conf.pstByqCode[i].uiOilTopTemp; + + stAdr.psadr[12].group = 3; // 运行工况组 + stAdr.psadr[12].btype = 13; // 绕组温度 + stAdr.psadr[12].sadr = g_iec_conf.pstByqCode[i].uiWindingTemp; + + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPosition, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTemperature, &stAdr); + + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressEntry, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressOuter, &stAdr); + + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempEntry, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempOuter, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPillowLevel, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTopTemp, &stAdr); + setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiWindingTemp, &stAdr); + if (stAdr.psadr) free(stAdr.psadr); + stAdr.psadr = NULL; + } + for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) + { + ST_SADR_MATCH stAdr; + memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH)); + stAdr.eqm_type = 2; + stAdr.count = 2; + stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST)); + + stAdr.psadr[0].group = 4; + stAdr.psadr[0].btype = 1; // 断开电流 + stAdr.psadr[0].sadr = g_iec_conf.pstBrkCode[i].uiAbortCurrent; + + stAdr.psadr[1].group = 4; + stAdr.psadr[1].btype = 2; // 断开电压 + stAdr.psadr[1].sadr = g_iec_conf.pstBrkCode[i].uiAbortVoltage; + setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortVoltage, &stAdr); + setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortCurrent, &stAdr); + if (stAdr.psadr) free(stAdr.psadr); + stAdr.psadr = NULL; + } + return true; } // 打印IEC104配置参数 static void showIEC104Conf() { - int i = 0; - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: iec_byq_count = %d, iec_break_count = %d", g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yx_start_addr = %d-(0x%04x)", g_iec_conf.yx_start_addr, g_iec_conf.yx_start_addr); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yx_stop_addr = %d-(0x%04x)", g_iec_conf.yx_stop_addr, g_iec_conf.yx_stop_addr); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: jb_start_addr = %d-(0x%04x)", g_iec_conf.jb_start_addr, g_iec_conf.jb_start_addr); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: jb_stop_addr = %d-(0x%04x)", g_iec_conf.jb_stop_addr, g_iec_conf.jb_stop_addr); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yc_start_addr = %d-(0x%04x)", g_iec_conf.yc_start_addr, g_iec_conf.yc_start_addr); - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yc_stop_addr = %d-(0x%04x)", g_iec_conf.yc_stop_addr, g_iec_conf.yc_stop_addr); - for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: BYQ_%02d Eqm_code = %s [%d,%d,%d,%d---%d,%d,%d,%d]", i+1, g_iec_conf.pstByqCode[i].szEqmCode, - g_iec_conf.pstByqCode[i].uiHighVoltage, g_iec_conf.pstByqCode[i].uiHighCurrent, - g_iec_conf.pstByqCode[i].uiLowVoltage, g_iec_conf.pstByqCode[i].uiLowCurrent, - g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry, g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter, - g_iec_conf.pstByqCode[i].uiOilTemperature, g_iec_conf.pstByqCode[i].uiOilPosition); - - for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: GIS_%02d Eqm_code(A,B,C) = (%s,%s,%s [%d,%d])", - i+1, g_iec_conf.pstBrkCode[i].szEqmCodeA, g_iec_conf.pstBrkCode[i].szEqmCodeB, g_iec_conf.pstBrkCode[i].szEqmCodeC, - g_iec_conf.pstBrkCode[i].uiAbortVoltage, g_iec_conf.pstBrkCode[i].uiAbortCurrent); - - // 显示点表地址匹配关系map - vPrtLogMsg(LOG_DEBUG, RET_OK, "---> g_map_sadr: size= %d", g_map_sadr.size()); + int i = 0; + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: iec_byq_count = %d, iec_break_count = %d", g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yx_start_addr = %d-(0x%04x)", g_iec_conf.yx_start_addr, g_iec_conf.yx_start_addr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yx_stop_addr = %d-(0x%04x)", g_iec_conf.yx_stop_addr, g_iec_conf.yx_stop_addr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: jb_start_addr = %d-(0x%04x)", g_iec_conf.jb_start_addr, g_iec_conf.jb_start_addr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: jb_stop_addr = %d-(0x%04x)", g_iec_conf.jb_stop_addr, g_iec_conf.jb_stop_addr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yc_start_addr = %d-(0x%04x)", g_iec_conf.yc_start_addr, g_iec_conf.yc_start_addr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: yc_stop_addr = %d-(0x%04x)", g_iec_conf.yc_stop_addr, g_iec_conf.yc_stop_addr); + for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: BYQ_%02d Eqm_code = %s [%d,%d,%d,%d---%d,%d,%d,%d]", i + 1, g_iec_conf.pstByqCode[i].szEqmCode, + g_iec_conf.pstByqCode[i].uiHighVoltage, g_iec_conf.pstByqCode[i].uiHighCurrent, + g_iec_conf.pstByqCode[i].uiLowVoltage, g_iec_conf.pstByqCode[i].uiLowCurrent, + g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry, g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter, + g_iec_conf.pstByqCode[i].uiOilTemperature, g_iec_conf.pstByqCode[i].uiOilPosition); + + for (i = 0; i < (int)g_iec_conf.iec_break_count; i++) + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: GIS_%02d Eqm_code(A,B,C) = (%s,%s,%s [%d,%d])", + i + 1, g_iec_conf.pstBrkCode[i].szEqmCodeA, g_iec_conf.pstBrkCode[i].szEqmCodeB, g_iec_conf.pstBrkCode[i].szEqmCodeC, + g_iec_conf.pstBrkCode[i].uiAbortVoltage, g_iec_conf.pstBrkCode[i].uiAbortCurrent); + + // 显示点表地址匹配关系map + vPrtLogMsg(LOG_DEBUG, RET_OK, "---> g_map_sadr: size= %d", g_map_sadr.size()); } + + +void WakeUpRecvLoop() +{ +#ifndef _WIN32 + if (g_IecCtrl.pipeFds[3] != -1) + { + int data = -1; + write(g_IecCtrl.pipeFds[1], &data, sizeof(data)); +} +#endif +} + +void WakeUpSendLoop() +{ +#ifndef _WIN32 + if (g_IecCtrl.pipeFds[1] != -1) + { + int data = -1; + write(g_IecCtrl.pipeFds[1], &data, sizeof(data)); + } +#endif +} + +void InitIecCtrl(ST_IEC104_CTRL& iecCtrl) +{ + iecCtrl.t0 = (int)g_TConfig.getTimeout0(); + iecCtrl.t1 = (int)g_TConfig.getTimeout1(); + iecCtrl.t2 = (int)g_TConfig.getTimeout2(); + iecCtrl.t3 = (int)g_TConfig.getTimeout3(); + iecCtrl.k = (int)g_TConfig.getK(); + iecCtrl.w = (int)g_TConfig.getW(); + iecCtrl.timer_S_Ackflag = true; + iecCtrl.timer_U_Testflag = true; // 初始化为真,如果过程中有超时,置为false + iecCtrl.m_gis_change = false; + iecCtrl.time_action = time(NULL); // 总召间隔时间更新 +} + void InitIECENV() { - memset(&g_IecCtrl, 0x00, sizeof(ST_IEC104_CTRL)); + memset(&g_IecCtrl, 0x00, sizeof(ST_IEC104_CTRL)); g_IecCtrl.sockid = -1; #ifndef _WIN32 g_IecCtrl.pipeFds[0] = -1; g_IecCtrl.pipeFds[1] = -1; + g_IecCtrl.pipeFds[2] = -1; + g_IecCtrl.pipeFds[3] = -1; #endif - g_IecCtrl.t0 = (int)g_TConfig.getTimeout0(); - g_IecCtrl.t1 = (int)g_TConfig.getTimeout1(); - g_IecCtrl.t2 = (int)g_TConfig.getTimeout2(); - g_IecCtrl.t3 = (int)g_TConfig.getTimeout3(); - g_IecCtrl.k = (int)g_TConfig.getK(); - g_IecCtrl.w = (int)g_TConfig.getW(); - g_IecCtrl.timer_S_Ackflag = true; - g_IecCtrl.timer_U_Testflag = true; // 初始化为真,如果过程中有超时,置为false - g_IecCtrl.m_gis_change = false; - g_IecCtrl.time_action = time(NULL); // 总召间隔时间更新 + g_IecCtrl.t0 = (int)g_TConfig.getTimeout0(); + g_IecCtrl.t1 = (int)g_TConfig.getTimeout1(); + g_IecCtrl.t2 = (int)g_TConfig.getTimeout2(); + g_IecCtrl.t3 = (int)g_TConfig.getTimeout3(); + g_IecCtrl.k = (int)g_TConfig.getK(); + g_IecCtrl.w = (int)g_TConfig.getW(); + g_IecCtrl.timer_S_Ackflag = true; + g_IecCtrl.timer_U_Testflag = true; // 初始化为真,如果过程中有超时,置为false + g_IecCtrl.m_gis_change = false; + g_IecCtrl.time_action = time(NULL); // 总召间隔时间更新 #ifndef _WIN32 pipe(g_IecCtrl.pipeFds); + pipe(&g_IecCtrl.pipeFds[2]); #endif } void IEC104EnvLoad() { - mutex_create(g_list_pack_mutex); - mutex_create(g_list_dbset_mutex); - mutex_create(g_sendno_mutex); - mutex_create(g_list_origin_mutex); + mutex_create(g_list_pack_mutex); + mutex_create(g_list_dbset_mutex); + mutex_create(g_sendno_mutex); + mutex_create(g_list_origin_mutex); mutex_create(g_list_origin_mutex_new); mutex_create(g_list_busi_data_mutex); - mutex_create(g_list_pingce_mutex); - mutex_create(g_list_warn_mutex); - g_list_pack.clear(); - g_list_dbset.clear(); - g_list_origin.clear(); + mutex_create(g_list_pingce_mutex); + mutex_create(g_list_warn_mutex); + g_list_pack.clear(); + g_list_dbset.clear(); + g_list_origin.clear(); g_list_origin_new.clear(); g_list_busi_data.clear(); - g_list_pingce.clear(); - g_list_warn.clear(); - InitIECENV(); - iGetIEC104Conf(); - //InitIECPointTable(); + g_list_pingce.clear(); + g_list_warn.clear(); + InitIECENV(); + iGetIEC104Conf(); + //InitIECPointTable(); #ifdef _DEBUG - showIEC104Conf(); + showIEC104Conf(); #endif } @@ -782,8 +829,7 @@ void IEC104EnvFree() #ifndef _WIN32 if (g_IecCtrl.pipeFds[1] != -1) { - int data = -1; - write(g_IecCtrl.pipeFds[1], &data, sizeof(data)); + WakeUpSendLoop(); close(g_IecCtrl.pipeFds[1]); g_IecCtrl.pipeFds[1] = -1; } @@ -792,122 +838,154 @@ void IEC104EnvFree() close(g_IecCtrl.pipeFds[0]); g_IecCtrl.pipeFds[0] = -1; } + + if (g_IecCtrl.pipeFds[3] != -1) + { + WakeUpRecvLoop(); + close(g_IecCtrl.pipeFds[3]); + g_IecCtrl.pipeFds[3] = -1; + } + if (g_IecCtrl.pipeFds[2] != -1) + { + close(g_IecCtrl.pipeFds[2]); + g_IecCtrl.pipeFds[2] = -1; + } #endif - mutex_close(g_list_pack_mutex); - mutex_close(g_list_dbset_mutex); - mutex_close(g_sendno_mutex); - mutex_close(g_list_origin_mutex); + mutex_close(g_list_pack_mutex); + mutex_close(g_list_dbset_mutex); + mutex_close(g_sendno_mutex); + mutex_close(g_list_origin_mutex); mutex_close(g_list_origin_mutex_new); mutex_close(g_list_busi_data_mutex); - mutex_close(g_list_pingce_mutex); - mutex_close(g_list_warn_mutex); - g_list_pack.clear(); - g_list_dbset.clear(); - g_list_origin.clear(); - g_list_pingce.clear(); - g_list_warn.clear(); + mutex_close(g_list_pingce_mutex); + mutex_close(g_list_warn_mutex); + g_list_pack.clear(); + g_list_dbset.clear(); + g_list_origin.clear(); + g_list_pingce.clear(); + g_list_warn.clear(); } -// last action time. -void UpdateLastTime() +// 添加报文到解析队列 +void MakePack(ST_IEC104_CTRL* pIecCtrl, unsigned char *pbuf, int bufLen, ST_RECVPKG& stPack) { - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.last_time = time(NULL); - mutex_unlock(g_IecCtrl_mutex); + ST_APCI *pstAPCI = (ST_APCI*)pbuf; + + memset(&stPack, 0x00, sizeof(ST_RECVPKG)); + + stPack.usISUType = (pstAPCI->cntl1 & 0x03); + if (stPack.usISUType == 0 || stPack.usISUType == 2) + { + stPack.usSendNo = 2 + ((pstAPCI->cntl2 << 8) | pstAPCI->cntl1); // 发送序号 + stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + } + else if (stPack.usISUType == 3) { + stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + } + + stPack.pszBuff = (unsigned char*)calloc(1, bufLen + 1); + if (stPack.pszBuff == NULL) + { + vPrtLogMsg(LOG_WARNG, RET_CALLOC_FAIL, "calloc failed."); + return; + } + memcpy(stPack.pszBuff, pbuf, bufLen); + stPack.iLength = bufLen; } // 添加报文到解析队列 -void AddParserList(unsigned char *pbuf, int bufLen) -{ - ST_RECVPKG stPack; - - ST_APCI *pstAPCI = (ST_APCI*)pbuf; - - memset(&stPack, 0x00, sizeof(ST_RECVPKG)); - - stPack.usISUType = (pstAPCI->cntl1 & 0x03); - if (stPack.usISUType == 0 || stPack.usISUType == 2) - { - stPack.usSendNo = 2 + ((pstAPCI->cntl2 << 8) | pstAPCI->cntl1); // 发送序号 - stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 - } - else if (stPack.usISUType == 3) { - stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 - } - - stPack.pszBuff = (unsigned char*)calloc(1, bufLen + 1); - if (stPack.pszBuff == NULL) - { - vPrtLogMsg(LOG_WARNG, RET_CALLOC_FAIL, "calloc failed."); - return; - } - memcpy(stPack.pszBuff, pbuf, bufLen); - stPack.iLength = bufLen; - - mutex_lock(g_list_pack_mutex); - g_list_pack.push_front(stPack); - mutex_unlock(g_list_pack_mutex); +void AddParserList(ST_IEC104_CTRL* pIecCtrl, unsigned char *pbuf, int bufLen) +{ + ST_RECVPKG stPack; + + ST_APCI *pstAPCI = (ST_APCI*)pbuf; + + memset(&stPack, 0x00, sizeof(ST_RECVPKG)); + + stPack.sockid = pIecCtrl->sockid; + stPack.usISUType = (pstAPCI->cntl1 & 0x03); + if (stPack.usISUType == 0 || stPack.usISUType == 2) + { + stPack.usSendNo = 2 + ((pstAPCI->cntl2 << 8) | pstAPCI->cntl1); // 发送序号 + stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + } + else if (stPack.usISUType == 3) { + stPack.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + } + + stPack.pszBuff = (unsigned char*)calloc(1, bufLen + 1); + if (stPack.pszBuff == NULL) + { + vPrtLogMsg(LOG_WARNG, RET_CALLOC_FAIL, "calloc failed."); + return; + } + memcpy(stPack.pszBuff, pbuf, bufLen); + stPack.iLength = bufLen; + + mutex_lock(g_list_pack_mutex); + g_list_pack.push_front(stPack); + mutex_unlock(g_list_pack_mutex); } //ST_IEC104_DATA //添加到入库队列 // pkgtype= 类型:1-运行工况 2:断路器数据 3:变压器负荷数据 static void addDbSetList(char *pdata, int length, char ctype) { - int i = 0; - ST_DB_DATA stSetData; - - memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); - stSetData.pData = (unsigned char*)calloc(1, length); - if (stSetData.pData == NULL) - { - vPrtLogMsg(LOG_WARNG, RET_CALLOC_FAIL, "calloc failed."); - return; - } - memcpy(stSetData.pData, pdata, length); - stSetData.ctype = (ctype & 0xff); //类型:1 - 运行工况 2 : 断路器数据 3 : 变压器负荷数据 - stSetData.iLength = length; - - mutex_lock(g_list_dbset_mutex); - g_list_dbset.push_front(stSetData); - mutex_unlock(g_list_dbset_mutex); + int i = 0; + ST_DB_DATA stSetData; + + memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); + stSetData.pData = (unsigned char*)calloc(1, length); + if (stSetData.pData == NULL) + { + vPrtLogMsg(LOG_WARNG, RET_CALLOC_FAIL, "calloc failed."); + return; + } + memcpy(stSetData.pData, pdata, length); + stSetData.ctype = (ctype & 0xff); //类型:1 - 运行工况 2 : 断路器数据 3 : 变压器负荷数据 + stSetData.iLength = length; + + mutex_lock(g_list_dbset_mutex); + g_list_dbset.push_front(stSetData); + mutex_unlock(g_list_dbset_mutex); } // 添加告警数据队列 static void addWarningTableList(ST_IECPOINT_TABLE &stData) { - int i = 0; - ST_IECPOINT_TABLE stSetData; - memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); - memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); - - mutex_lock(g_list_warn_mutex); - g_list_warn.push_front(stSetData); - mutex_unlock(g_list_warn_mutex); + int i = 0; + ST_IECPOINT_TABLE stSetData; + memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); + memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); + + mutex_lock(g_list_warn_mutex); + g_list_warn.push_front(stSetData); + mutex_unlock(g_list_warn_mutex); } // 添加断路器断开状态数据队列 static void addGisDataList(ST_IECPOINT_TABLE &stData) { - int i = 0; - ST_IECPOINT_TABLE stSetData; - memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); - memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); - - mutex_lock(g_list_pingce_mutex); - g_list_pingce.push_front(stSetData); - mutex_unlock(g_list_pingce_mutex); + int i = 0; + ST_IECPOINT_TABLE stSetData; + memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); + memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); + + mutex_lock(g_list_pingce_mutex); + g_list_pingce.push_front(stSetData); + mutex_unlock(g_list_pingce_mutex); } // 添加原始数据入库队列 static void addOriginDataList(ST_IECPOINT_TABLE &stData) { - int i = 0; - ST_IECPOINT_TABLE stSetData; + int i = 0; + ST_IECPOINT_TABLE stSetData; - memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); - memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); + memset(&stSetData, 0x00, sizeof(ST_DB_DATA)); + memcpy(&stSetData, &stData, sizeof(ST_IECPOINT_TABLE)); - mutex_lock(g_list_origin_mutex); - g_list_origin.push_front(stSetData); - mutex_unlock(g_list_origin_mutex); + mutex_lock(g_list_origin_mutex); + g_list_origin.push_front(stSetData); + mutex_unlock(g_list_origin_mutex); } // 添加原始数据入库队列 @@ -925,143 +1003,143 @@ static void addOriginDataListNew(const IEC_OBJVAL_NEW &stData) } // 获取发送序列号 -void vAutoSendSeqNo(int b) +void vAutoSendSeqNo(ST_IEC104_CTRL* pIecCtrl, int b) { - mutex_lock(g_sendno_mutex); - if (g_IecCtrl.usSendNo > 16384) - g_IecCtrl.usSendNo = 0; - else g_IecCtrl.usSendNo += b; - mutex_unlock(g_sendno_mutex); + mutex_lock(g_sendno_mutex); + if (pIecCtrl->usSendNo > 16384) + pIecCtrl->usSendNo = 0; + else pIecCtrl->usSendNo += b; + mutex_unlock(g_sendno_mutex); } // TX U-Format Message (APCI only) -int SendMsgFormatU(int cmd) +int SendMsgFormatU(ST_IEC104_CTRL* pIecCtrl, int cmd) { - int iRet = -1; - if (g_Tcp.tcpIsConnected(g_IecCtrl.sockid)) - { - ST_APCI header; - header.start = 0x68; - header.len = 0x04; - header.cntl1 = 0x03 | cmd; // U-Format - header.cntl2 = 0; - header.cntl3 = 0; // g_IecCtrl.usRecvNo & 0xFE; - header.cntl4 = 0; //(g_IecCtrl.usRecvNo >> 8) & 0xFF; + int iRet = -1; + if (g_Tcp.tcpIsConnected(pIecCtrl->sockid)) + { + ST_APCI header; + header.start = 0x68; + header.len = 0x04; + header.cntl1 = 0x03 | cmd; // U-Format + header.cntl2 = 0; + header.cntl3 = 0; // pIecCtrl.usRecvNo & 0xFE; + header.cntl4 = 0; //(pIecCtrl.usRecvNo >> 8) & 0xFF; #ifndef _WIN32 - iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, sizeof(ST_APCI), g_IecCtrl.pipeFds[0]); + iRet = g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&header, sizeof(ST_APCI), pIecCtrl->pipeFds[0]); #else - iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, sizeof(ST_APCI), -1); + iRet = g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&header, sizeof(ST_APCI), -1); #endif - if (iRet == ErrException) - { - vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", g_IecCtrl.sockid, strerror(errno)); - g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, MAX_SBUFF_TCP); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; - } - //g_IecCtrl.usSendNo++; - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); - } - return iRet; + if (iRet == ErrException) + { + vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", pIecCtrl->sockid, strerror(errno)); + g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; + } + //g_IecCtrl.usSendNo++; + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); + } + return iRet; } // 发送S格式报文 -int SendMsgFormatS(unsigned short sendno) +int SendMsgFormatS(ST_IEC104_CTRL* pIecCtrl, unsigned short sendno) { - if (!g_IecCtrl.isConnect || g_IecCtrl.sockid <= 0) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "send S package, No socket connection, send cancel.sockid=%d isConn=%d", g_IecCtrl.sockid, g_IecCtrl.isConnect); - return 0; - } - - ST_APCI header; - int iRet = -1; - header.start = 0x68; - header.len = 0x04; - - header.cntl1 = 0x01; // S-Format - header.cntl2 = 0x00; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 - header.cntl3 = sendno & 0xFE; // 应答对端的接收序列号 - header.cntl4 = (sendno >> 8) & 0xFF; - - //header.cntl1 = (g_IecCtrl.RxCounter & 0xFE); // S-Format - //header.cntl2 = (g_IecCtrl.RxCounter >> 8) & 0xFF; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 - //header.cntl3 = (g_IecCtrl.TxCounter & 0xFE); // S-Format - //header.cntl4 = (g_IecCtrl.TxCounter >> 8) & 0xFF; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 - - int sockid = g_IecCtrl.sockid; + if (!pIecCtrl->isConnect || pIecCtrl->sockid <= 0) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "send S package, No socket connection, send cancel.sockid=%d isConn=%d", pIecCtrl->sockid, pIecCtrl->isConnect); + return 0; + } + + ST_APCI header; + int iRet = -1; + header.start = 0x68; + header.len = 0x04; + + header.cntl1 = 0x01; // S-Format + header.cntl2 = 0x00; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 + header.cntl3 = sendno & 0xFE; // 应答对端的接收序列号 + header.cntl4 = (sendno >> 8) & 0xFF; + + //header.cntl1 = (pIecCtrl.RxCounter & 0xFE); // S-Format + //header.cntl2 = (pIecCtrl.RxCounter >> 8) & 0xFF; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 + //header.cntl3 = (pIecCtrl.TxCounter & 0xFE); // S-Format + //header.cntl4 = (pIecCtrl.TxCounter >> 8) & 0xFF; //S格式确认包,cnt1=0x01, cnt2=0x00,是固定不变的。 + + int sockid = pIecCtrl->sockid; #ifndef _WIN32 - if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)&header, sizeof(ST_APCI), g_IecCtrl.pipeFds[0])) < 0) + if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)&header, sizeof(ST_APCI), g_IecCtrl.pipeFds[0])) < 0) #else if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)&header, sizeof(ST_APCI), -1)) < 0) #endif - { - vPrtLogMsg(LOG_WARNG, iRet, "send Format S failed with error: %s, errno=%d will close socket", strerror(errno), errno); - if (sockid == g_IecCtrl.sockid) + { + vPrtLogMsg(LOG_WARNG, iRet, "send Format S failed with error: %s, errno=%d will close socket", strerror(errno), errno); + if (sockid == pIecCtrl->sockid) { - g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, MAX_SBUFF_TCP); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; + g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; } - return iRet; - } - //g_IecCtrl.usSendNo++; - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); - return iRet; + return iRet; + } + //g_IecCtrl.usSendNo++; + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); + return iRet; } // TX I-Format Message (always contains ASDU) -int SendMsgFormatI(unsigned char *msgbuf, unsigned int len) +int SendMsgFormatI(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len) { - if (!g_IecCtrl.isConnect || g_IecCtrl.sockid <= 0) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "send I package, No socket connection, send cancel.sockid=%d isConn=%d", g_IecCtrl.sockid, g_IecCtrl.isConnect); - return 0; - } - char buf[1024]; - int iRet = -1; - ST_APCI *header = (ST_APCI*)buf; - vAutoSendSeqNo(1); // 发送序列号增1 - header->start = 0x68; - header->len = 0x04 + len; - header->cntl1 = g_IecCtrl.usSendNo & 0xFE; // I-Format - header->cntl2 = ((g_IecCtrl.usSendNo >> 8) & 0xFF); - header->cntl3 = (g_IecCtrl.usRecvNo & 0xFE); // I-Format - header->cntl4 = ((g_IecCtrl.usRecvNo >> 8) & 0xFF); - - memcpy(buf + sizeof(ST_APCI), msgbuf, len); - int sockid = g_IecCtrl.sockid; + if (!pIecCtrl->isConnect || pIecCtrl->sockid <= 0) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "send I package, No socket connection, send cancel.sockid=%d isConn=%d", pIecCtrl->sockid, pIecCtrl->isConnect); + return 0; + } + char buf[1024]; + int iRet = -1; + ST_APCI *header = (ST_APCI*)buf; + vAutoSendSeqNo(pIecCtrl, 1); // 发送序列号增1 + header->start = 0x68; + header->len = 0x04 + len; + header->cntl1 = pIecCtrl->usSendNo & 0xFE; // I-Format + header->cntl2 = ((pIecCtrl->usSendNo >> 8) & 0xFF); + header->cntl3 = (pIecCtrl->usRecvNo & 0xFE); // I-Format + header->cntl4 = ((pIecCtrl->usRecvNo >> 8) & 0xFF); + + memcpy(buf + sizeof(ST_APCI), msgbuf, len); + int sockid = pIecCtrl->sockid; #ifndef _WIN32 - if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)buf, len + sizeof(ST_APCI), g_IecCtrl.pipeFds[0])) < 0) + if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)buf, len + sizeof(ST_APCI), g_IecCtrl.pipeFds[0])) < 0) #else if ((iRet = g_Tcp.tcpSendBuffer(sockid, (const char*)buf, len + sizeof(ST_APCI), -1)) < 0) #endif - { - vPrtLogMsg(LOG_WARNG, iRet, "send Format I failed with error: %s, errno=%d will close socket", strerror(errno), errno); + { + vPrtLogMsg(LOG_WARNG, iRet, "send Format I failed with error: %s, errno=%d will close socket", strerror(errno), errno); if (sockid == g_IecCtrl.sockid) - g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, MAX_SBUFF_TCP); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; - return iRet; - } - // g_IecCtrl.usSendNo++; - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)buf, len + sizeof(ST_APCI)); - return iRet; + g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; + return iRet; + } + // pIecCtrl.usSendNo++; + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_SEND, (unsigned char*)buf, len + sizeof(ST_APCI)); + return iRet; } -int Interrogate(int asdu, int group) +int Interrogate(ST_IEC104_CTRL* pIecCtrl, int asdu, int group) { - ST_ASDU msg; - msg.header.type = 0x64; // interrogation command - msg.header.qual = 0x01; // number of elements - msg.header.tx_cause1 = 0x06; // activation - msg.header.tx_cause2 = 0x00; - msg.header.commom_asdu1 = asdu & 0xFF; - msg.header.commom_asdu2 = (asdu >> 8) & 0xFF; - // 貌似少了3个字节的信息体地址 - // group information - msg.data[0] = 0x00; - msg.data[1] = 0x00; - msg.data[2] = 0x00; - msg.data[3] = 20 + group; - return SendMsgFormatI((unsigned char*)&msg, 10); + ST_ASDU msg; + msg.header.type = 0x64; // interrogation command + msg.header.qual = 0x01; // number of elements + msg.header.tx_cause1 = 0x06; // activation + msg.header.tx_cause2 = 0x00; + msg.header.commom_asdu1 = asdu & 0xFF; + msg.header.commom_asdu2 = (asdu >> 8) & 0xFF; + // 貌似少了3个字节的信息体地址 + // group information + msg.data[0] = 0x00; + msg.data[1] = 0x00; + msg.data[2] = 0x00; + msg.data[3] = 20 + group; + return SendMsgFormatI(pIecCtrl, (unsigned char*)&msg, 10); } /*************************************************************************** ** 函数名:thread_listen_proc 启动服务线程 @@ -1071,161 +1149,174 @@ int Interrogate(int asdu, int group) ***************************************************************************/ void* thread_listen_proc(void * arg) { - int server_fd, accept_fd; - - vPrtLogMsg(LOG_DEBUG, 0, "thread_listen_proc = %d startup...", GETTID()); - //从链路启动服务 - server_fd = g_Tcp.tcpOpenServer(g_TConfig.getLocalAddr(), g_TConfig.getLocalPort()); - if (server_fd <= 0) { - vPrtLogMsg(LOG_ERROR, server_fd, "Local server:%s:%d startup failed.", g_TConfig.getLocalAddr(), g_TConfig.getLocalPort()); - g_Running = 0; - return NULL; - } - g_Tcp.tcpSetServerfd(server_fd); - - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.listenid = server_fd; - mutex_unlock(g_IecCtrl_mutex); - - while (g_Running) - { - pthread_testcancels(); - accept_fd = g_Tcp.tcpAcceptSocket(server_fd); - if (accept_fd < 0) - { + int server_fd, accept_fd; + + vPrtLogMsg(LOG_DEBUG, 0, "thread_listen_proc = %d startup...", GETTID()); + //从链路启动服务 + server_fd = g_Tcp.tcpOpenServer(g_TConfig.getLocalAddr(), g_TConfig.getLocalPort()); + if (server_fd <= 0) { + vPrtLogMsg(LOG_ERROR, server_fd, "Local server:%s:%d startup failed.", g_TConfig.getLocalAddr(), g_TConfig.getLocalPort()); + g_Running = 0; + return NULL; + } + g_Tcp.tcpSetServerfd(server_fd); + + while (g_Running) + { + pthread_testcancels(); + accept_fd = g_Tcp.tcpAcceptSocket(server_fd); + if (accept_fd < 0) + { /* - mutex_lock(g_IecCtrl_mutex); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.last_time = 0; - g_IecCtrl.sockid = -1; - g_IecCtrl.isConnect = false; - mutex_unlock(g_IecCtrl_mutex); - _SLEEP(1000); + mutex_lock(g_IecCtrl_mutex); + g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); + g_IecCtrl.last_time = 0; + g_IecCtrl.sockid = -1; + g_IecCtrl.isConnect = false; + mutex_unlock(g_IecCtrl_mutex); + _SLEEP(1000); */ - // vPrtLogMsg(LOG_DEBUG, errno,"slave link waitting connect...accept_fd=%d", accept_fd); - continue; - } - mutex_lock(g_IecCtrl_mutex); - int org_socket = g_IecCtrl.sockid; - if (org_socket != -1) - { - // Will close it, wake it up - + // vPrtLogMsg(LOG_DEBUG, errno,"slave link waitting connect...accept_fd=%d", accept_fd); + continue; + } + + ST_IEC104_CTRL iecCtrl; + memset(&iecCtrl, 0x00, sizeof(iecCtrl)); + InitIecCtrl(iecCtrl); + + iecCtrl.isConnect = true; + time_t ts = time(NULL); + iecCtrl.last_time = ts; + iecCtrl.last_yx_time = ts; + iecCtrl.last_yc_time = ts; + iecCtrl.sockid = accept_fd; + + ST_IEC104_CTRL* pIecCtrl = NULL; + mutex_lock(g_IecCtrl_mutex); + // Will close it, wake it up #ifndef _WIN32 - if (g_IecCtrl.pipeFds[1] != -1) - { - write(g_IecCtrl.pipeFds[1], &org_socket, sizeof(org_socket)); - vPrtLogMsg(LOG_ERROR, errno, "Wake up socket select via pipe,sockid:%d", org_socket); - } + // if (g_IecCtrl.pipeFds[1] != -1) + { + // write(g_IecCtrl.pipeFds[1], &org_socket, sizeof(org_socket)); + // vPrtLogMsg(LOG_ERROR, errno, "Wake up socket select via pipe,sockid:%d", org_socket); + } #endif - } - // g_Tcp.tcpCloseSocket(org_socket); - - mutex_unlock(g_IecCtrl_mutex); - _SLEEP(1000); - - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.last_time = time(NULL); - g_IecCtrl.last_yx_time = time(NULL); - g_IecCtrl.last_yc_time = time(NULL); - g_IecCtrl.sockid = accept_fd; - g_IecCtrl.isConnect = true; - - mutex_unlock(g_IecCtrl_mutex); - - - pthread_t thread_handle_minor_recv = -1; - pthread_t thread_handle_minor_active = -1; - _SLEEP(3000); // 给主链路时间,来处理登录应答. + +// #if defined(_WIN32) && defined(_DEBUG) + std::map::iterator it = g_IecCtrls.find(accept_fd); + if (it != g_IecCtrls.end()) + { + it->second.isConnect = false; + g_Tcp.tcpCloseSocket(it->second.sockid); + } +// #endif + + g_IecCtrls[accept_fd] = iecCtrl; + pIecCtrl = &(g_IecCtrls[accept_fd]); + + int maxSockId = -1; + for (std::map::iterator it = g_IecCtrls.begin(); it != g_IecCtrls.end(); ++it) + { + if (it->first > maxSockId) + { + maxSockId = it->first; + } + } + g_MaxScokId = maxSockId; + mutex_unlock(g_IecCtrl_mutex); + + pthread_t thread_handle_minor_recv = -1; + pthread_t thread_handle_minor_active = -1; + // _SLEEP(3000); // 给主链路时间,来处理登录应答. #ifndef _WIN32 - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 创建一个分离子线程 + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 创建一个分离子线程 #endif - g_Tcp.tcpSetSockID(accept_fd); - vPrtLogMsg(LOG_DEBUG, errno, "connect link the recv socket fd is: %d", g_IecCtrl.sockid); - //ht_pthread_create_background(&thread_handle_minor_recv, thread_recv_proc, NULL); - //ht_pthread_create_background(&thread_handle_minor_active, thread_active_proc, NULL); + g_Tcp.tcpSetSockID(accept_fd); + vPrtLogMsg(LOG_DEBUG, errno, "connect link the recv socket fd is: %d", accept_fd); + ht_pthread_create_background(&thread_handle_minor_recv, thread_recv_proc, (void *)pIecCtrl); + ht_pthread_create_background(&thread_handle_minor_active, thread_active_proc, (void *)pIecCtrl); #ifndef _WIN32 - //pthread_detach(thread_handle_minor_recv); - //ptread_detach(thread_handle_minor_active); + pthread_detach(thread_handle_minor_recv); + pthread_detach(thread_handle_minor_active); #endif - _SLEEP(1000); - } - g_Tcp.tcpCloseSocket(server_fd); - vPrtLogMsg(LOG_DEBUG, errno, "shutdown accept addr=%s:%d, socket_id: %d", g_TConfig.getLocalAddr(), g_TConfig.getLocalPort(), server_fd); - return NULL; + _SLEEP(1000); + } + g_Tcp.tcpCloseSocket(server_fd); + vPrtLogMsg(LOG_DEBUG, errno, "shutdown accept addr=%s:%d, socket_id: %d", g_TConfig.getLocalAddr(), g_TConfig.getLocalPort(), server_fd); + return NULL; } // 添加104子站服务不能连接的告警消息 -void vSetIEC104StationsWarnMesg() +void vSetIEC104StationsWarnMesg(ST_IEC104_CTRL* pIecCtrl) { - int i = 0; - char eqm_code[64] = { 0 }, szuuid[64] = { 0 }; - char szSql[DEF_BUFFER_1K] = { 0 }; - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) { - return; - } - vGetHostTimeFmt(g_IecCtrl.m_iec_warn_time); - for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - { - getuuid(szuuid, sizeof(szuuid)); - strcpy(eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode); - snprintf(szSql,sizeof(szSql), "INSERT INTO busi_eqm_warning(id,eq_type,gz_type,warning_msg,warning_time,create_time," - "del_flag,site_id,main_tree_id,run_state) " - "VALUES('%s','1', '9', '104子站服务异常断开,请检查服务!', '%s', SYSDATE(), '1', '%s', '%s','0')", - szuuid,g_IecCtrl.m_iec_warn_time, g_iec_conf.site_id, eqm_code); - - vPrtLogMsg(LOG_DEBUG, RET_OK, "insert IECService Warning: %s", szSql); - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql); - } - - // 插入告警详细表 - char szSubUuid[64] = { 0 }; - char szWarninfo[512] = { 0 }; - getuuid(szSubUuid, sizeof(szSubUuid)); - memset(szSql, 0x00, sizeof(szSql)); - - snprintf(szWarninfo, sizeof(szWarninfo), - "{\"sadr\":\"\",\"thresholdValue\":\"\",\"currRealValue\":\"\",\"equipmentStatus\":\"\",\"collectDate\":\"%s\",\"ipaddr\":\"%s\",\"port\":\"%d\",\"msgInfo\":\"%s\",\"phase\":\"\"}", - g_IecCtrl.m_iec_warn_time, g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(),"IEC104服务链路"); - snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning_info(id,warning_id,warning_info) " - "VALUES('%s','%s','%s')", - szSubUuid, szuuid, szWarninfo); - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning_info message failed,SQL:%s", szSql); - } - } + int i = 0; + char eqm_code[64] = { 0 }, szuuid[64] = { 0 }; + char szSql[DEF_BUFFER_1K] = { 0 }; + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) { + return; + } + vGetHostTimeFmt(pIecCtrl->m_iec_warn_time); + for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + { + getuuid(szuuid, sizeof(szuuid)); + strcpy(eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode); + snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(id,eq_type,gz_type,warning_msg,warning_time,create_time," + "del_flag,site_id,main_tree_id,run_state) " + "VALUES('%s','1', '9', '104子站服务异常断开,请检查服务!', '%s', SYSDATE(), '1', '%s', '%s','0')", + szuuid, pIecCtrl->m_iec_warn_time, g_iec_conf.site_id, eqm_code); + + vPrtLogMsg(LOG_DEBUG, RET_OK, "insert IECService Warning: %s", szSql); + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql); + } + + // 插入告警详细表 + char szSubUuid[64] = { 0 }; + char szWarninfo[512] = { 0 }; + getuuid(szSubUuid, sizeof(szSubUuid)); + memset(szSql, 0x00, sizeof(szSql)); + + snprintf(szWarninfo, sizeof(szWarninfo), + "{\"sadr\":\"\",\"thresholdValue\":\"\",\"currRealValue\":\"\",\"equipmentStatus\":\"\",\"collectDate\":\"%s\",\"ipaddr\":\"%s\",\"port\":\"%d\",\"msgInfo\":\"%s\",\"phase\":\"\"}", + g_IecCtrl.m_iec_warn_time, g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(), "IEC104服务链路"); + snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning_info(id,warning_id,warning_info) " + "VALUES('%s','%s','%s')", + szSubUuid, szuuid, szWarninfo); + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning_info message failed,SQL:%s", szSql); + } + } } // 删除104子站服务不能连接的告警消息 -void vDelIEC104StationsWarnMesg() +void vDelIEC104StationsWarnMesg(ST_IEC104_CTRL* pIecCtrl) { - int i = 0; - char eqm_code[64] = { 0 }; - char szSql[DEF_BUFFER_1K] = { 0 }; - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) { - return; - } - for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - { - strcpy(eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode); - if (strlen(g_IecCtrl.m_iec_warn_time) > 0 ) - snprintf(szSql, sizeof(szSql), "update busi_eqm_warning set del_flag='2', deal_status='1',processing_time=sysdate(),deal_msg='system service auto resume.'," - "processing_user='system' where site_id='%s' and eq_type='1' and gz_type='9' and main_tree_id='%s' and warning_time='%s' and " - "warning_msg='104子站服务异常断开,请检查服务!' ", g_iec_conf.site_id, eqm_code, g_IecCtrl.m_iec_warn_time); - else - snprintf(szSql, sizeof(szSql), "update busi_eqm_warning set del_flag='2', deal_status='1',processing_time=sysdate(),deal_msg='system service auto resume.'," - "processing_user='system' where site_id='%s' and eq_type='1' and gz_type='9' and main_tree_id='%s' and " - "warning_msg='104子站服务异常断开,请检查服务!' ", g_iec_conf.site_id, eqm_code); - - vPrtLogMsg(LOG_DEBUG, RET_OK, "update IECService Warning: %s", szSql); - if (!pdbHandle->UpdateRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "update busi_eqm_warning message failed,SQL:%s", szSql); - } - } + int i = 0; + char eqm_code[64] = { 0 }; + char szSql[DEF_BUFFER_1K] = { 0 }; + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) { + return; + } + for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + { + strcpy(eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode); + if (strlen(pIecCtrl->m_iec_warn_time) > 0) + snprintf(szSql, sizeof(szSql), "update busi_eqm_warning set del_flag='2', deal_status='1',processing_time=sysdate(),deal_msg='system service auto resume.'," + "processing_user='system' where site_id='%s' and eq_type='1' and gz_type='9' and main_tree_id='%s' and warning_time='%s' and " + "warning_msg='104子站服务异常断开,请检查服务!' ", g_iec_conf.site_id, eqm_code, g_IecCtrl.m_iec_warn_time); + else + snprintf(szSql, sizeof(szSql), "update busi_eqm_warning set del_flag='2', deal_status='1',processing_time=sysdate(),deal_msg='system service auto resume.'," + "processing_user='system' where site_id='%s' and eq_type='1' and gz_type='9' and main_tree_id='%s' and " + "warning_msg='104子站服务异常断开,请检查服务!' ", g_iec_conf.site_id, eqm_code); + + vPrtLogMsg(LOG_DEBUG, RET_OK, "update IECService Warning: %s", szSql); + if (!pdbHandle->UpdateRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "update busi_eqm_warning message failed,SQL:%s", szSql); + } + } } /*************************************************************************** ** function name : thread_linkmgr_proc @@ -1235,71 +1326,176 @@ void vDelIEC104StationsWarnMesg() ***************************************************************************/ void *thread_client_proc(void *arg) { - bool bWarn = true; - vPrtLogMsg(LOG_DEBUG, 0, "thread_client_proc = %d startup...", GETTID()); - g_IecCtrl.b_Signal = false; - g_IecCtrl.m_gis_fault_count = 0; -// g_IecCtrl.m_gis_count = 0; - while (g_Running) - { - pthread_testcancels(); - - if (g_Tcp.tcpIsConnected(g_IecCtrl.sockid) && g_IecCtrl.isConnect) { - _SLEEP(5000); // 5秒钟检查一次链路是否正常 - continue; - } - else if (g_IecCtrl.sockid > 0) - { - mutex_lock(g_IecCtrl_mutex); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.last_time = 0; - g_IecCtrl.sockid = -1; - g_IecCtrl.isConnect = false; - InitIECENV(); - mutex_unlock(g_IecCtrl_mutex); - } - vPrtLogMsg(LOG_DEBUG, 0, "Connect to server:%s:%d start...", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort()); - //创建客户端 - g_IecCtrl.sockid = g_Tcp.tcpConnect(g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(), 30); // t0 = 30s - if (g_IecCtrl.sockid <= 0) { - vPrtLogMsg(LOG_ERROR, g_IecCtrl.sockid, "Connect to server:%s:%d failed.", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort()); - if (bWarn) { - vSetIEC104StationsWarnMesg(); - bWarn = false; - } - _SLEEP(5000); - continue; - } - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.last_time = time(NULL); - g_IecCtrl.isConnect = true; - mutex_unlock(g_IecCtrl_mutex); - SendMsgFormatU(CMD_STARTDT); // 发送激活命令 - pthread_t thread_handle_minor_recv = -1; - pthread_t thread_handle_minor_active = -1; - g_Internal_time = time(NULL); - //_SLEEP(3000) ; + bool bWarn = true; + vPrtLogMsg(LOG_DEBUG, 0, "thread_client_proc = %d startup...", GETTID()); + + ST_IEC104_CTRL iecCtrl; + memset(&iecCtrl, 0x00, sizeof(ST_IEC104_CTRL)); + + InitIecCtrl(iecCtrl); + + iecCtrl.isConnect = false; + iecCtrl.sockid = -1; + iecCtrl.b_Signal = false; + iecCtrl.m_gis_fault_count = 0; + + // g_IecCtrl.m_gis_count = 0; + while (g_Running) + { + pthread_testcancels(); + + if (iecCtrl.isConnect && g_Tcp.tcpIsConnected(iecCtrl.sockid)) + { + _SLEEP(5000); // 5秒钟检查一次链路是否正常 + continue; + } + else if (iecCtrl.sockid > 0) + { + // mutex_lock(g_IecCtrl_mutex); + g_Tcp.tcpCloseSocket(iecCtrl.sockid); + iecCtrl.last_time = 0; + iecCtrl.sockid = -1; + iecCtrl.isConnect = false; + InitIECENV(); + } + vPrtLogMsg(LOG_DEBUG, 0, "Connect to server:%s:%d start...", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort()); + //创建客户端 + iecCtrl.sockid = g_Tcp.tcpConnect(g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(), 30); // t0 = 30s + if (g_IecCtrl.sockid <= 0) { + vPrtLogMsg(LOG_ERROR, iecCtrl.sockid, "Connect to server:%s:%d failed.", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort()); + if (bWarn) { + vSetIEC104StationsWarnMesg(&iecCtrl); + bWarn = false; + } + _SLEEP(5000); + continue; + } + + iecCtrl.last_time = time(NULL); + iecCtrl.isConnect = true; + + SendMsgFormatU(&iecCtrl, CMD_STARTDT); // 发送激活命令 + pthread_t thread_handle_minor_recv = -1; + pthread_t thread_handle_minor_active = -1; + g_Internal_time = time(NULL); + //_SLEEP(3000); +#ifndef _WIN32 + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 创建一个分离子线程,接收数据线程 +#endif + vPrtLogMsg(LOG_DEBUG, errno, "connect link the recv socket fd is: %d", g_IecCtrl.sockid); + ht_pthread_create_background(&thread_handle_minor_recv, thread_recv_proc, NULL); + ht_pthread_create_background(&thread_handle_minor_active, thread_active_proc, NULL); +#ifndef _WIN32 + pthread_detach(thread_handle_minor_recv); + pthread_detach(thread_handle_minor_active); +#endif + _SLEEP(1000); + bWarn = true; + vDelIEC104StationsWarnMesg(&iecCtrl); // 链路自动恢复后,处理链路告警:以处理 + } + g_Tcp.tcpCloseSocket(iecCtrl.sockid); + iecCtrl.isConnect = false; + vPrtLogMsg(LOG_DEBUG, errno, "shutdown thread_client_proc, server_addr=%s:%d, socket_id: %d", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(), iecCtrl.sockid); + + return NULL; +} + +size_t ParseData(ST_IEC104_CTRL* pIecCtrl, unsigned char* buf, size_t len) +{ + size_t bytes_in_buf = len; + + size_t offset = 0; + size_t pkgLen = 0; + while (offset < len) + { + // Find HEAD + if ((buf[offset] & 0xff) != CMD_START_HEAD) + { + // Ignore it + offset++; + continue; + } + + if (len - offset < (int)sizeof(ST_APCI)) // < 6byte + { + break; + } + + pkgLen = 1 + 1 + (buf[offset + 1] & 0xff); + if (bytes_in_buf - offset < pkgLen) + { + break; + } + + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_RECV, (unsigned char*)buf, pkgLen); + + ST_RECVPKG stPack; + MakePack(pIecCtrl, buf + offset, pkgLen, stPack); + offset += pkgLen; + + // 解析104报文 + if (stPack.iLength >= MIN_APDU_LENGTH && (stPack.pszBuff[0] & 0xff) == CMD_START_HEAD) // 0x68H + { + ST_APCI *pstAPCI = (ST_APCI*)stPack.pszBuff; + pIecCtrl->usISUType = (pstAPCI->cntl1 & 0x03); + pIecCtrl->usSendNo = (pstAPCI->cntl2 << 8) | pstAPCI->cntl1; // 发送序号 + pIecCtrl->usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + + if (pIecCtrl->usISUType == 0 || pIecCtrl->usISUType == 2) // I Format package + { + pIecCtrl->timer_S_Ackflag = false; // 收到I格式帧的时候置为false, 超时的时候置为true. + pIecCtrl->RxCounter = pIecCtrl->usSendNo++; + pIecCtrl->LastAckTx = pIecCtrl->usRecvNo; + SendMsgFormatS(pIecCtrl, stPack.usSendNo); // 应答 + DecodeMsgFormatI(pIecCtrl, stPack.pszBuff + sizeof(ST_APCI), stPack.iLength - sizeof(ST_APCI), stPack.usSendNo); // 解析报文 + } + else if (pIecCtrl->usISUType == 1) // S Format package + { + //DecodeMsgFormatS(pData.pszBuff + sizeof(ST_APCI), pData.iLength - sizeof(ST_APCI)); + } + else if (pIecCtrl->usISUType == 3) // U Format package + { + DecodeMsgFormatU(pIecCtrl, pstAPCI); // U Format package + pIecCtrl->usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; + pIecCtrl->LastAckTx = g_IecCtrl.usRecvNo; + } + pIecCtrl->timer_U_Testflag = false; // 接收到I S U格式的帧都需要重置,表示t3内已经接收到报文 + } + if (stPack.pszBuff != NULL) free(stPack.pszBuff); + stPack.pszBuff = NULL; + } + + return offset; +} + +void CloseSocket(int sockid) +{ + g_Tcp.clear_tcp_buffer(sockid, MAX_SBUFF_TCP); + + ST_IEC104_CTRL iecCtrl; + iecCtrl.sockid = -1; + + std::map::iterator it; + mutex_lock(g_IecCtrl_mutex); + it = g_IecCtrls.find(sockid); + if (it != g_IecCtrls.end()) + { + iecCtrl = it->second; + g_IecCtrls.erase(it); + #ifndef _WIN32 - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 创建一个分离子线程,接收数据线程 + WakeUpSendLoop(); + WakeUpRecvLoop(); #endif - vPrtLogMsg(LOG_DEBUG, errno, "connect link the recv socket fd is: %d", g_IecCtrl.sockid); - ht_pthread_create_background(&thread_handle_minor_recv, thread_recv_proc, NULL); - ht_pthread_create_background(&thread_handle_minor_active, thread_active_proc, NULL); -#ifndef _WIN32 - pthread_detach(thread_handle_minor_recv); - pthread_detach(thread_handle_minor_active); -#endif - _SLEEP(1000); - bWarn = true; - vDelIEC104StationsWarnMesg(); // 链路自动恢复后,处理链路告警:以处理 - } - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; - vPrtLogMsg(LOG_DEBUG, errno, "shutdown thread_client_proc, server_addr=%s:%d, socket_id: %d", g_TConfig.getRemoteAddr(), g_TConfig.getRemotePort(), g_IecCtrl.sockid); - - return NULL; + } + mutex_unlock(g_IecCtrl_mutex); + + if (iecCtrl.sockid != -1) + { + g_Tcp.tcpCloseSocket(iecCtrl.sockid); + } } /*************************************************************************** @@ -1310,106 +1506,170 @@ void *thread_client_proc(void *arg) ***************************************************************************/ void* thread_recv_proc(void * arg) { - unsigned char szBuf[MAX_SBUFF_TCP] = { 0 }; - int recv_buflen = 0, pkgLen = 0; + ST_IEC104_CTRL* pIecCtrl = (ST_IEC104_CTRL *)arg; + + unsigned char buf[MAX_SBUFF_TCP] = { 0 }; + int recv_buflen = 0, pkgLen = 0; int recv_offset = 0; int bytes_in_buf = 0; int offset = 0; - vPrtLogMsg(LOG_DEBUG, 0, "thread_recv_proc = %d startup, sockid=%d...", GETTID(), g_IecCtrl.sockid); +#if 0 + vPrtLogMsg(LOG_DEBUG, 0, "thread_recv_proc = %d startup, sockid=%d...", GETTID(), pIecCtrl->sockid); +#endif + + int maxSockId = pIecCtrl->sockid; - while (g_Running ) + fd_set fd_Read, fd_Except; + struct timeval st_TimeOut; + int isel = 0; + int timeout = 10; + int err_code = 0; + + while (g_Running && pIecCtrl->isConnect) { pthread_testcancels(); - if (!g_IecCtrl.isConnect) - { - _SLEEP(1000); - continue; - } - memset(szBuf, 0x00, sizeof(szBuf)); - recv_buflen = -1; - int sockid = g_IecCtrl.sockid; - recv_buflen = g_Tcp.tcpRecvBuffer(sockid, (char*)szBuf, MAX_SBUFF_TCP, 5); // t1 = 15s - if (recv_buflen == ErrException || (recv_buflen == 0 && errno == 2)) { - vPrtLogMsg(LOG_WARNG, errno, "socket link exceptiond, do close sockid=%d, thread_recv_proc pthread_exit.", g_IecCtrl.sockid); - g_Tcp.clear_tcp_buffer(sockid, MAX_SBUFF_TCP); - - - mutex_lock(g_IecCtrl_mutex); - if (sockid == g_IecCtrl.sockid) - { - g_IecCtrl.isConnect = false; - g_IecCtrl.sockid = -1; - } - mutex_unlock(g_IecCtrl_mutex); - break; + + FD_ZERO(&fd_Read); + FD_ZERO(&fd_Except); + +#ifndef _WIN32 + if (g_IecCtrl.pipeFds[3] != -1) + { + if (g_IecCtrl.pipeFds[3] > maxSockId) + { + maxSockId = g_IecCtrl.pipeFds[3]; + } + FD_SET((unsigned int)g_IecCtrl.pipeFds[3], &fd_Read); } - else if (recv_buflen <= 0) { - vPrtLogMsg(LOG_WARNG, RET_OK, "socket link recv data length: %d,sockid=%d,errno=%d, sleep and continue", recv_buflen, g_IecCtrl.sockid, errno); +#endif + size_t offset; + struct timeval st_TimeOut; + + st_TimeOut.tv_sec = timeout; + st_TimeOut.tv_usec = 0; + + FD_SET((unsigned int)pIecCtrl->sockid, &fd_Read); + FD_SET((unsigned int)pIecCtrl->sockid, &fd_Except); + + if (maxSockId == -1) + { _SLEEP(1000); continue; } - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.last_time = time(NULL); - mutex_unlock(g_IecCtrl_mutex); - - bytes_in_buf = recv_buflen; - - offset = 0; - pkgLen = 0; - while (offset < bytes_in_buf) + isel = select(maxSockId + 1, &fd_Read, NULL, &fd_Except, &st_TimeOut); + err_code = errno; + if (isel == 0) { - // Find HEAD - if ((szBuf[offset] & 0xff) != CMD_START_HEAD) + vPrtLogMsg(LOG_DEBUG, err_code, "select socket timeout,isel=%d,timeout=%d continue", isel, timeout); + continue; + } + if (isel < 0) + { + err_code = errno; + if (err_code == EINTR || err_code == EAGAIN) { - // Ignore it - offset++; + vPrtLogMsg(LOG_DEBUG, err_code, "select socket error EINTR/EAGAIN,isel=%d continue", isel, err_code); continue; } - if (bytes_in_buf - offset < (int)sizeof(ST_APCI)) // < 6byte + vPrtLogMsg(LOG_DEBUG, err_code, "select socket error,isel=%d, errno=%d", isel, err_code); + break; + } + +#ifndef _WIN32 + if (g_IecCtrl.pipeFds[3] != -1 && FD_ISSET(g_IecCtrl.pipeFds[3], &fd_Read)) + { + continue; + } +#endif + + if (FD_ISSET(pIecCtrl->sockid, &fd_Except)) + { + vPrtLogMsg(LOG_ERROR, errno, "socket execption,sockid:%d errno:%d iselect:%d", pIecCtrl->sockid, errno, isel); + continue; + } + + if (FD_ISSET(pIecCtrl->sockid, &fd_Read)) //检测Socket读状态 + { + recv_buflen = recv(pIecCtrl->sockid, (char *)buf, MAX_SBUFF_TCP, MSG_PEEK); // MSG_PEEK +#ifdef _WIN32 + err_code = WSAGetLastError(); +#else + err_code = errno; +#endif + if (recv_buflen < 0) { - break; - } +#ifdef _WIN32 + if (err_code == WSAEINTR || err_code == WSAEWOULDBLOCK) - pkgLen = 1 + 1 + (szBuf[offset + 1] & 0xff); - if (bytes_in_buf - offset < pkgLen) +#else + if (err_code == EINTR || err_code == EWOULDBLOCK || err_code == EAGAIN) +#endif + { + continue; + } + else + { + // g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; + continue; + } + } + else if (recv_buflen == 0) { - break; + // vPrtLogMsg(LOG_DEBUG, errno, "select socket timeout,isel=%d nLength=%d", isel, nLength); + // socket is closed + // g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; + CloseSocket(pIecCtrl->sockid); + continue; + } + else + { + offset = ParseData(pIecCtrl, buf, recv_buflen); + if (offset > 0) + { + g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, offset); + } } - - AddParserList(szBuf + offset, pkgLen); - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_RECV, (unsigned char*)szBuf, pkgLen); - offset += pkgLen; } + } - if (offset > 0) - { - g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, offset); - } - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "link exceptiond, thread_recv_proc pthread_exit."); - return NULL; + _SLEEP(1000); + + mutex_lock(g_IecCtrl_mutex); + std::map::iterator it; + it = g_IecCtrls.find(pIecCtrl->sockid); + if (it != g_IecCtrls.end()) + { + g_IecCtrls.erase(it); + } + mutex_unlock(g_IecCtrl_mutex); + vPrtLogMsg(LOG_DEBUG, RET_OK, "link exceptiond, thread_recv_proc pthread_exit."); + return NULL; } //遥控执行 -void vYaoKongExe(unsigned char *msgbuf, unsigned int len) +void vYaoKongExe(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len) { - msgbuf[2] = 0x06; - msgbuf[9] = 0x01; - SendMsgFormatI(msgbuf, len); + msgbuf[2] = 0x06; + msgbuf[9] = 0x01; + SendMsgFormatI(pIecCtrl, msgbuf, len); } //遥控撤销 -void vYaoKongUnexe(unsigned char *msgbuf, unsigned int len) +void vYaoKongUnexe(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len) { - msgbuf[2] = 0x08; - SendMsgFormatI(msgbuf, len); + msgbuf[2] = 0x08; + SendMsgFormatI(pIecCtrl, msgbuf, len); } // 遥信值入map -bool bSetPointTableValueYX(unsigned char v, unsigned int adr) +bool bSetPointTableValueYX(ST_IEC104_CTRL* pIecCtrl, unsigned char v, unsigned int adr) { IEC_OBJVAL_NEW objVal = { 0 }; objVal.stype = 1; @@ -1419,50 +1679,50 @@ bool bSetPointTableValueYX(unsigned char v, unsigned int adr) addOriginDataListNew(objVal); - bool is_state_opend = false; - unsigned char ovl = 0; - map::iterator m_pIter; - mutex_lock(g_map_iec_mutex); - m_pIter = g_map_iec.find(adr); - if (m_pIter != g_map_iec.end()) - { - if (((m_pIter->second).stype & 0xff) == 0x01) - { - (m_pIter->second).dtime = time(NULL)-1; - // 遥信量tcpAcceptSocket - if ((v & 0xff) != ((m_pIter->second).cval & 0xff)) - { - ovl = ((m_pIter->second).cval & 0xff); // 上一次的状态值 - (m_pIter->second).cval = (v & 0xff); - g_IecCtrl.b_Signal = true; - g_IecCtrl.stime = time(NULL); - - // 根据配置文件GIS的点位配置,抓取断路器断开状态 - if (((ovl & 0xff) == YX_STAT_CLOSE) && ((v & 0xff) == YX_STAT_OPEND)) // 原状态位合1,且新状态位0,表示断路器断开一次 - { - addGisDataList(m_pIter->second); // 记录一次断开数据 - } - - if (((m_pIter->second).eqm_type & 0xff) == 0x01) - { - (m_pIter->second).wstate = getDevWorkState(m_pIter->second); // 刷新主变工作状态 - SethDevTimeStat((m_pIter->second).sys_code, (m_pIter->second).wstate); - vPrtLogMsg(LOG_DEBUG, RET_OK, "YX addr:%d(0x%04x) set val=%d, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).cval, (m_pIter->second).eqm_code,(m_pIter->second).wstate); - (m_pIter->second).bfault = getDevFaultState(m_pIter->second); // 刷新主变事故状态 - } - - if (((m_pIter->second).eqm_type & 0xff) == 0x02) //刷新GIS开关开合状态 - { - flushDevCloseState((m_pIter->second).site_id, (m_pIter->second).eqm_code, (m_pIter->second).cval); - } - addOriginDataList(m_pIter->second); // 原始数据入库队列 - vPrtLogMsg(LOG_DEBUG, RET_OK, "YX addr:%d(0x%04x) set val=%d", adr, adr, (m_pIter->second).cval); - } - } - } - mutex_unlock(g_map_iec_mutex); - - return true; + bool is_state_opend = false; + unsigned char ovl = 0; + map::iterator m_pIter; + mutex_lock(g_map_iec_mutex); + m_pIter = g_map_iec.find(adr); + if (m_pIter != g_map_iec.end()) + { + if (((m_pIter->second).stype & 0xff) == 0x01) + { + (m_pIter->second).dtime = time(NULL) - 1; + // 遥信量tcpAcceptSocket + if ((v & 0xff) != ((m_pIter->second).cval & 0xff)) + { + ovl = ((m_pIter->second).cval & 0xff); // 上一次的状态值 + (m_pIter->second).cval = (v & 0xff); + pIecCtrl->b_Signal = true; + pIecCtrl->stime = time(NULL); + + // 根据配置文件GIS的点位配置,抓取断路器断开状态 + if (((ovl & 0xff) == YX_STAT_CLOSE) && ((v & 0xff) == YX_STAT_OPEND)) // 原状态位合1,且新状态位0,表示断路器断开一次 + { + addGisDataList(m_pIter->second); // 记录一次断开数据 + } + + if (((m_pIter->second).eqm_type & 0xff) == 0x01) + { + (m_pIter->second).wstate = getDevWorkState(m_pIter->second); // 刷新主变工作状态 + SethDevTimeStat((m_pIter->second).sys_code, (m_pIter->second).wstate); + vPrtLogMsg(LOG_DEBUG, RET_OK, "YX addr:%d(0x%04x) set val=%d, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).cval, (m_pIter->second).eqm_code, (m_pIter->second).wstate); + (m_pIter->second).bfault = getDevFaultState(m_pIter->second); // 刷新主变事故状态 + } + + if (((m_pIter->second).eqm_type & 0xff) == 0x02) //刷新GIS开关开合状态 + { + flushDevCloseState((m_pIter->second).site_id, (m_pIter->second).eqm_code, (m_pIter->second).cval); + } + addOriginDataList(m_pIter->second); // 原始数据入库队列 + vPrtLogMsg(LOG_DEBUG, RET_OK, "YX addr:%d(0x%04x) set val=%d", adr, adr, (m_pIter->second).cval); + } + } + } + mutex_unlock(g_map_iec_mutex); + + return true; } bool bSetPointTableValueYX(const std::vector& values) @@ -1498,7 +1758,7 @@ bool bSetPointTableValueYC(float v, unsigned int adr) map::iterator itCachedDev; bool assigned = false; - + list::iterator itBusiData; mutex_lock(g_map_iec_mutex_new); itPoint = g_map_iec_new.find(adr); @@ -1530,69 +1790,65 @@ bool bSetPointTableValueYC(float v, unsigned int adr) mutex_unlock(g_map_iec_mutex_new); } - map::iterator m_pIter; - double oldval = 0.0; - mutex_lock(g_map_iec_mutex); - m_pIter = g_map_iec.find(adr); - if (m_pIter != g_map_iec.end()) - { + map::iterator m_pIter; + double oldval = 0.0; + mutex_lock(g_map_iec_mutex); + m_pIter = g_map_iec.find(adr); + if (m_pIter != g_map_iec.end()) + { vPrtLogMsg(LOG_DEBUG, RET_OK, "bSetPointTableValueYC:%d(0x%04x) set style=%d added OriginDataList", adr, adr, (m_pIter->second).stype); - if (((m_pIter->second).stype & 0xff) == 2) - { - // 遥测量 - oldval = (m_pIter->second).fval; - (m_pIter->second).dtime = time(NULL); - (m_pIter->second).fval = getChangeUnit((m_pIter->second).unit, (m_pIter->second).sysunit, v); // 单位转换 - if (((m_pIter->second).eqm_type & 0xff) == 1) - (m_pIter->second).wstate = cGetByqDeviceState((m_pIter->second).eqm_code); - else (m_pIter->second).wstate = cGetCurrentWorkState((m_pIter->second).eqm_code); // 获取工作状态 - - if (strlen((char*)(m_pIter->second).fieldname) > 0) { - addWarningTableList(m_pIter->second); - } + if (((m_pIter->second).stype & 0xff) == 2) + { + // 遥测量 + oldval = (m_pIter->second).fval; + (m_pIter->second).dtime = time(NULL); + (m_pIter->second).fval = getChangeUnit((m_pIter->second).unit, (m_pIter->second).sysunit, v); // 单位转换 + if (((m_pIter->second).eqm_type & 0xff) == 1) + (m_pIter->second).wstate = cGetByqDeviceState((m_pIter->second).eqm_code); + else (m_pIter->second).wstate = cGetCurrentWorkState((m_pIter->second).eqm_code); // 获取工作状态 + + if (strlen((char*)(m_pIter->second).fieldname) > 0) { + addWarningTableList(m_pIter->second); + } #ifdef _DEF_DB_CHANGERATE - #if 0 - if (g_IecCtrl.b_Signal) { - vPrtLogMsg(LOG_WARNG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).fval, (m_pIter->second).eqm_code, (m_pIter->second).wstate); - addPingCeTableList(m_pIter->second); - g_IecCtrl.b_Signal = false; - } - else if (bCompare(oldval, (m_pIter->second).fval, (m_pIter->second).devrate) && !g_IecCtrl.b_Signal) - { // 计算偏差率 - //vPrtLogMsg(LOG_WARNG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f-%.4f-%.4f, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).fval,oldval,v, (m_pIter->second).eqm_code, (m_pIter->second).wstate); - vPrtLogMsg(LOG_WARNG, RET_OK, "bCompare olv=%.4f nlv=%.4f sadr=%d rate=%.2f",oldval,(m_pIter->second).fval, adr, (m_pIter->second).devrate); +#if 0 + if (g_IecCtrl.b_Signal) { + vPrtLogMsg(LOG_WARNG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).fval, (m_pIter->second).eqm_code, (m_pIter->second).wstate); addPingCeTableList(m_pIter->second); - } - - if ((time(NULL) - g_Internal_time) >= (g_iec_conf.save_internal)) { // 间隔时间保存数据 - vPrtLogMsg(LOG_WARNG, RET_OK, "(time(NULL) - g_Internal_time) =%d internal=%d", (time(NULL) - g_Internal_time), g_iec_conf.save_internal); - addPingCeTableList(m_pIter->second); - g_Internal_time = time(NULL); - } - #endif + g_IecCtrl.b_Signal = false; + } + else if (bCompare(oldval, (m_pIter->second).fval, (m_pIter->second).devrate) && !g_IecCtrl.b_Signal) + { // 计算偏差率 + //vPrtLogMsg(LOG_WARNG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f-%.4f-%.4f, eqid=%s wstatue=%d", adr, adr, (m_pIter->second).fval,oldval,v, (m_pIter->second).eqm_code, (m_pIter->second).wstate); + vPrtLogMsg(LOG_WARNG, RET_OK, "bCompare olv=%.4f nlv=%.4f sadr=%d rate=%.2f", oldval, (m_pIter->second).fval, adr, (m_pIter->second).devrate); + addPingCeTableList(m_pIter->second); + } + + if ((time(NULL) - g_Internal_time) >= (g_iec_conf.save_internal)) { // 间隔时间保存数据 + vPrtLogMsg(LOG_WARNG, RET_OK, "(time(NULL) - g_Internal_time) =%d internal=%d", (time(NULL) - g_Internal_time), g_iec_conf.save_internal); + addPingCeTableList(m_pIter->second); + g_Internal_time = time(NULL); + } #endif - if ((m_pIter->second).isget == 1 && bCompare(oldval, (m_pIter->second).fval, (m_pIter->second).devrate)) // 是否提取 - { - addOriginDataList(m_pIter->second); // 原始数据入库队列 +#endif + if ((m_pIter->second).isget == 1 && bCompare(oldval, (m_pIter->second).fval, (m_pIter->second).devrate)) // 是否提取 + { + addOriginDataList(m_pIter->second); // 原始数据入库队列 vPrtLogMsg(LOG_DEBUG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f added OriginDataList", adr, adr, (m_pIter->second).fval); - } + } //vPrtLogMsg(LOG_DEBUG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f", adr, adr, (m_pIter->second).fval); - } - } - - mutex_unlock(g_map_iec_mutex); - return true; + } + } + + mutex_unlock(g_map_iec_mutex); + return true; } bool bSetPointTableValueYC(const std::vector& values) { - - - - - + /* IEC_OBJVAL_NEW objVal = { 0 }; objVal.stype = 2; @@ -1609,99 +1865,99 @@ bool bSetPointTableValueYC(const std::vector& values) // I-Formar message decodification I格式帧解码 // msgbuf : asdu_header + asdu_body // len : asdu length -int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sendno) +int DecodeMsgFormatI(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len, unsigned short sendno) { - ST_ASDU_HEADER *header = NULL; - ST_OBJVAL stObj[DEF_BUFFER_256]; - unsigned char num = 0, cause = 0, n = 0; - bool seq = false; - int asdu = 0, idx = 0; - unsigned int pos = 0; - unsigned int adr; - - //ASDU = type(1) + limit(1) + cause(2) + gaddr(2) + objaddr(3) + data(1) + data(1) + ... - memset(stObj, 0x00, sizeof(ST_OBJVAL)*DEF_BUFFER_256); - /* - 可变结构限定词 = VARIABLE STRUCTURE QUALIFIER :=CP8{ number、SQ } - number = N = 数目 := UI7[1..7]<0..127> - <0> :=应用服务数据单元不含信息对象 - <1..127>:=应用服务数据单元信息元素(单个信息元素或同类信息元素组合)的数目 - SQ = 单个或者顺序 := BS1[8]<0..1> - <0> :=寻址同一种类型的许多信息对象中单个的信息元素或者信息元素的集合 - <1> :=寻址 ASDU 单个信息对象中顺序的单个信息元素信息元素的同类集合 - SQ<0>和 N<0..127>∶ = 信息对象的数目 I (一个地址+一个元素)*N - SQ<1>和 N<0..127>∶ = 每个应用服务数据单元中单个对象的信息元素或者信息元素的 - 集合的数目 j (一个地址,后接连续 N 个元素) - SQ 位规定寻址后续信息对象或单个信息元素 / 信息元素集合的方法。 - SQ := 0 由信息对象地址寻址的单个信息元素或信息元素集合。应用服务数据单 - 元可以由一个或者多个同类的信息对象所组成。数目 N 是一个二进制数,它定义了信息对 - 象的数目。 - SQ := 1 单个信息元素或者信息元素同类集合的序列(即同一种格式测量值)由信 - 息对象地址来寻址(见 IEC 60870 - 5 - 3 中的 5.1.5), 信息对象地址是顺序单个信息元素或者信 - 息元素集合的第一个信息元素或者集合的地址。后续单个信息元素或者信息元素集合的地 - 址是从这个地址起顺序加 1。数目 N 是一个二进制数,它定义了单个信息元素或者信息元 - 素集合的数目。在顺序单个信息元素或者信息元素集合的情况下每个应用服务数据单元仅 - 安排一个信息对象. - */ - header = (ST_ASDU_HEADER*)msgbuf; - num = header->qual & 0x7F; // number of objects. 数据元素个数 - if (header->qual & 0x80) // sequence of objects ? 限定词,第一位:1=报文包含信息数据,0=不含信息数据 - seq = true; - /* - 传送原因 = CAUSE OF TRANSMISSION := CP16{ Cause, P / N, T, Originator Address(opt) } - 其中 Cause :=UI6[1..6]<0..63> - <0> := 未定义 - <1..63> :=传送原因序号 - <1..47> :=本配套标准的标准定义(兼容范围)见表 14 - <48..63> := 专用范围 - P/N ∶ = BS1[7]<0..1> - <0> ∶ = 肯定确认 - <1> ∶ = 否定确认 - T=test := BS1[8]<0..1> - <0>:=未试验 - <1>:=试验 - Originator address = 源发者地址 := UI8[9..16] - <0>:=缺省值 - <1..255> :=源发者地址号 - */ - cause = header->tx_cause1; // cause of tx.传送原因[1] - - /* 公共地址 :=UI16[1..16]<0..65535> - 其中 <0> :=未用 - <1..65534> :=站地址 - <65535> :=全局地址 */ - asdu = header->commom_asdu2 << 8; - asdu |= header->commom_asdu1; - if (asdu != g_iec_conf.iec_global_addr) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "Recv Common Address=0x%04x(%d), Dest Common Address=0x%04x(%d), Plase Checking Config!", asdu, asdu,g_iec_conf.iec_global_addr,g_iec_conf.iec_global_addr); - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "ASDU Common Address=0x%04x(%d) TypeID=%d Count=%d Cause=%d(0x%02x) seq=%d", asdu, asdu, header->type, num, cause, cause, seq); - - // type identification - // 第一个八位位组为类型标识(图 11), 它定义了后续信息对象的结构、类型和格式。 - // 类型标识定义如下: - // 类型标识=TYPE IDENTIFICATION:=UI8[1..8]<1..255> - // bit 8 7 6 5 4 3 2 1 - // 信息对象是否带时标由标识类型的不同序号来区分。 - // 控制站将舍弃那些类型标识未被定义的应用服务数据单元 - // 类型标识值<0>未用,在本配套标准中定义了 1 至 127 的值,128 至 255 未定义。136 - // 至 255 可以由此标准的使用者彼此独立的进行定义,仅当使用具有类型标识号为 1 至 127 - // 的范围的应用服务数据单元才能达到全部互操作。 + ST_ASDU_HEADER *header = NULL; + ST_OBJVAL stObj[DEF_BUFFER_256]; + unsigned char num = 0, cause = 0, n = 0; + bool seq = false; + int asdu = 0, idx = 0; + unsigned int pos = 0; + unsigned int adr; + + //ASDU = type(1) + limit(1) + cause(2) + gaddr(2) + objaddr(3) + data(1) + data(1) + ... + memset(stObj, 0x00, sizeof(ST_OBJVAL)*DEF_BUFFER_256); + /* + 可变结构限定词 = VARIABLE STRUCTURE QUALIFIER :=CP8{ number、SQ } + number = N = 数目 := UI7[1..7]<0..127> + <0> :=应用服务数据单元不含信息对象 + <1..127>:=应用服务数据单元信息元素(单个信息元素或同类信息元素组合)的数目 + SQ = 单个或者顺序 := BS1[8]<0..1> + <0> :=寻址同一种类型的许多信息对象中单个的信息元素或者信息元素的集合 + <1> :=寻址 ASDU 单个信息对象中顺序的单个信息元素信息元素的同类集合 + SQ<0>和 N<0..127>∶ = 信息对象的数目 I (一个地址+一个元素)*N + SQ<1>和 N<0..127>∶ = 每个应用服务数据单元中单个对象的信息元素或者信息元素的 + 集合的数目 j (一个地址,后接连续 N 个元素) + SQ 位规定寻址后续信息对象或单个信息元素 / 信息元素集合的方法。 + SQ := 0 由信息对象地址寻址的单个信息元素或信息元素集合。应用服务数据单 + 元可以由一个或者多个同类的信息对象所组成。数目 N 是一个二进制数,它定义了信息对 + 象的数目。 + SQ := 1 单个信息元素或者信息元素同类集合的序列(即同一种格式测量值)由信 + 息对象地址来寻址(见 IEC 60870 - 5 - 3 中的 5.1.5), 信息对象地址是顺序单个信息元素或者信 + 息元素集合的第一个信息元素或者集合的地址。后续单个信息元素或者信息元素集合的地 + 址是从这个地址起顺序加 1。数目 N 是一个二进制数,它定义了单个信息元素或者信息元 + 素集合的数目。在顺序单个信息元素或者信息元素集合的情况下每个应用服务数据单元仅 + 安排一个信息对象. + */ + header = (ST_ASDU_HEADER*)msgbuf; + num = header->qual & 0x7F; // number of objects. 数据元素个数 + if (header->qual & 0x80) // sequence of objects ? 限定词,第一位:1=报文包含信息数据,0=不含信息数据 + seq = true; + /* + 传送原因 = CAUSE OF TRANSMISSION := CP16{ Cause, P / N, T, Originator Address(opt) } + 其中 Cause :=UI6[1..6]<0..63> + <0> := 未定义 + <1..63> :=传送原因序号 + <1..47> :=本配套标准的标准定义(兼容范围)见表 14 + <48..63> := 专用范围 + P/N ∶ = BS1[7]<0..1> + <0> ∶ = 肯定确认 + <1> ∶ = 否定确认 + T=test := BS1[8]<0..1> + <0>:=未试验 + <1>:=试验 + Originator address = 源发者地址 := UI8[9..16] + <0>:=缺省值 + <1..255> :=源发者地址号 + */ + cause = header->tx_cause1; // cause of tx.传送原因[1] + + /* 公共地址 :=UI16[1..16]<0..65535> + 其中 <0> :=未用 + <1..65534> :=站地址 + <65535> :=全局地址 */ + asdu = header->commom_asdu2 << 8; + asdu |= header->commom_asdu1; + if (asdu != g_iec_conf.iec_global_addr) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "Recv Common Address=0x%04x(%d), Dest Common Address=0x%04x(%d), Plase Checking Config!", asdu, asdu, g_iec_conf.iec_global_addr, g_iec_conf.iec_global_addr); + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "ASDU Common Address=0x%04x(%d) TypeID=%d Count=%d Cause=%d(0x%02x) seq=%d", asdu, asdu, header->type, num, cause, cause, seq); + + // type identification + // 第一个八位位组为类型标识(图 11), 它定义了后续信息对象的结构、类型和格式。 + // 类型标识定义如下: + // 类型标识=TYPE IDENTIFICATION:=UI8[1..8]<1..255> + // bit 8 7 6 5 4 3 2 1 + // 信息对象是否带时标由标识类型的不同序号来区分。 + // 控制站将舍弃那些类型标识未被定义的应用服务数据单元 + // 类型标识值<0>未用,在本配套标准中定义了 1 至 127 的值,128 至 255 未定义。136 + // 至 255 可以由此标准的使用者彼此独立的进行定义,仅当使用具有类型标识号为 1 至 127 + // 的范围的应用服务数据单元才能达到全部互操作。 // std::vector ycItems; IEC_OBJVAL_NEW ycItem = { 2, 0 }; time_t ts = time(NULL); - - switch (header->type & 0xff) - { - case 1: // Single-point information - SIQ104 *pi; - if (seq) // 有序数据,即信息体地址[3]+data[1]+data[1]+... - { - SP104 *ps = (SP104*)&msgbuf[sizeof(ST_ASDU_HEADER)]; - adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl); - bSetPointTableValueYX(ps->siq.spi, adr); - + + switch (header->type & 0xff) + { + case 1: // Single-point information + SIQ104 *pi; + if (seq) // 有序数据,即信息体地址[3]+data[1]+data[1]+... + { + SP104 *ps = (SP104*)&msgbuf[sizeof(ST_ASDU_HEADER)]; + adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl); + bSetPointTableValueYX(pIecCtrl, ps->siq.spi, adr); + /* ycItem.stype = 1; ycItem.dtime = ts; @@ -1710,13 +1966,13 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItems.push_back(ycItem); */ - pos = sizeof(ST_ASDU_HEADER)+sizeof(SP104); - while (pos < len) - { - adr++; - pi = (SIQ104*)&msgbuf[pos]; + pos = sizeof(ST_ASDU_HEADER) + sizeof(SP104); + while (pos < len) + { + adr++; + pi = (SIQ104*)&msgbuf[pos]; // - bSetPointTableValueYX(pi->spi, adr); + bSetPointTableValueYX(pIecCtrl, pi->spi, adr); /* ycItem.stype = 1; @@ -1726,19 +1982,19 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItems.push_back(ycItem); */ - if (pi->spi) - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, pi->spi, pi->iv, pi->bl); - pos++; - } - if (cause == 3) SendMsgFormatS(sendno); // 突发上送之后发送S帧确认 - } - else { // 数据格式,即信息体地址[3]+data[1]+信息体地址[3]+data[1]+信息体地址[3]+data[1]+... - pos = sizeof(ST_ASDU_HEADER); - while (pos < len) - { - SP104 *ps = (SP104*)&msgbuf[pos]; - adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; - bSetPointTableValueYX(ps->siq.spi, adr); + if (pi->spi) + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, pi->spi, pi->iv, pi->bl); + pos++; + } + if (cause == 3) SendMsgFormatS(pIecCtrl, sendno); // 突发上送之后发送S帧确认 + } + else { // 数据格式,即信息体地址[3]+data[1]+信息体地址[3]+data[1]+信息体地址[3]+data[1]+... + pos = sizeof(ST_ASDU_HEADER); + while (pos < len) + { + SP104 *ps = (SP104*)&msgbuf[pos]; + adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; + bSetPointTableValueYX(pIecCtrl, ps->siq.spi, adr); /* ycItem.stype = 1; ycItem.dtime = ts; @@ -1747,74 +2003,74 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItems.push_back(ycItem); */ - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl); - pos += sizeof(SP104); - } - } - break; - case 9: // 短整数,测量值,归一化值 - pos = sizeof(ST_ASDU_HEADER); - if (seq) - { // 连续的值序列,常见于总召报文,即:3位信息地址+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]... - SH104 *pf = (SH104*)&msgbuf[pos]; - adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; - short *val = (short*)&pf->val[0]; - bSetPointTableValueYC(*val, adr); - + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl); + pos += sizeof(SP104); + } + } + break; + case 9: // 短整数,测量值,归一化值 + pos = sizeof(ST_ASDU_HEADER); + if (seq) + { // 连续的值序列,常见于总召报文,即:3位信息地址+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]... + SH104 *pf = (SH104*)&msgbuf[pos]; + adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; + short *val = (short*)&pf->val[0]; + bSetPointTableValueYC(*val, adr); + ycItem.stype = 2; ycItem.dtime = ts; ycItem.sadr = adr; ycItem.fval = *val; // ycItems.push_back(ycItem); - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); - pos += sizeof(SH104); - adr++; - while (pos < len) - { - SHP104 *pfv = (SHP104*)&msgbuf[pos]; - short *val = (short*)&pfv->val[0]; - bSetPointTableValueYC(*val, adr); - + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); + pos += sizeof(SH104); + adr++; + while (pos < len) + { + SHP104 *pfv = (SHP104*)&msgbuf[pos]; + short *val = (short*)&pfv->val[0]; + bSetPointTableValueYC(*val, adr); + ycItem.stype = 2; ycItem.dtime = ts; ycItem.sadr = adr; ycItem.fval = *val; // ycItems.push_back(ycItem); - if (*val) - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pfv->qds.ov, pfv->qds.iv, pfv->qds.bl); - pos += sizeof(SHP104); - adr++; - } - } - else { // 当有变化量时,连续的值序列,即:3位信息地址+[2字节的值+1字节的品质位]+3位信息地址+[2字节的值+1字节的品质位]+... - while (pos < len) - { - SH104 *pf = (SH104*)&msgbuf[pos]; - adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; - short *val = (short*)&pf->val[0]; - bSetPointTableValueYC(*val, adr); - + if (*val) + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pfv->qds.ov, pfv->qds.iv, pfv->qds.bl); + pos += sizeof(SHP104); + adr++; + } + } + else { // 当有变化量时,连续的值序列,即:3位信息地址+[2字节的值+1字节的品质位]+3位信息地址+[2字节的值+1字节的品质位]+... + while (pos < len) + { + SH104 *pf = (SH104*)&msgbuf[pos]; + adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; + short *val = (short*)&pf->val[0]; + bSetPointTableValueYC(*val, adr); + ycItem.stype = 2; ycItem.dtime = ts; ycItem.sadr = adr; ycItem.fval = *val; // ycItems.push_back(ycItem); - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); - pos += sizeof(SH104); - } - } - break; - case 13: // Measure value, short floating point value 短浮点数测量值 - pos = sizeof(ST_ASDU_HEADER); - if (seq) - { // 连续的值序列,常见于总召报文,即:3位信息地址+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]... - SFP104 *pf = (SFP104*)&msgbuf[pos]; - adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; - float *val = (float*)&pf->val[0]; - bSetPointTableValueYC(*val, adr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); + pos += sizeof(SH104); + } + } + break; + case 13: // Measure value, short floating point value 短浮点数测量值 + pos = sizeof(ST_ASDU_HEADER); + if (seq) + { // 连续的值序列,常见于总召报文,即:3位信息地址+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]... + SFP104 *pf = (SFP104*)&msgbuf[pos]; + adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; + float *val = (float*)&pf->val[0]; + bSetPointTableValueYC(*val, adr); ycItem.stype = 2; ycItem.dtime = ts; @@ -1823,13 +2079,13 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen // ycItems.push_back(ycItem); vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%-.4f OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); - pos += sizeof(SFP104); - adr++; - while (pos < len) - { - SFP104V *pfv = (SFP104V*)&msgbuf[pos]; - float *val = (float*)&pfv->val[0]; - bSetPointTableValueYC(*val, adr); + pos += sizeof(SFP104); + adr++; + while (pos < len) + { + SFP104V *pfv = (SFP104V*)&msgbuf[pos]; + float *val = (float*)&pfv->val[0]; + bSetPointTableValueYC(*val, adr); ycItem.stype = 2; ycItem.dtime = ts; @@ -1837,18 +2093,18 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItem.fval = *val; // ycItems.push_back(ycItem); - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%-.4f OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pfv->qds.ov, pfv->qds.iv, pfv->qds.bl); - pos += sizeof(SFP104V); - adr++; - } - } - else { // 当有变化量时,连续的值序列,即:3位信息地址+[4字节的值+1字节的品质位]+3位信息地址+[4字节的值+1字节的品质位]+... - while (pos < len) - { - SFP104 *pf = (SFP104*)&msgbuf[pos]; - adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; - float *val = (float*)&pf->val[0]; - bSetPointTableValueYC(*val, adr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%-.4f OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pfv->qds.ov, pfv->qds.iv, pfv->qds.bl); + pos += sizeof(SFP104V); + adr++; + } + } + else { // 当有变化量时,连续的值序列,即:3位信息地址+[4字节的值+1字节的品质位]+3位信息地址+[4字节的值+1字节的品质位]+... + while (pos < len) + { + SFP104 *pf = (SFP104*)&msgbuf[pos]; + adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; + float *val = (float*)&pf->val[0]; + bSetPointTableValueYC(*val, adr); ycItem.stype = 2; ycItem.dtime = ts; @@ -1857,20 +2113,20 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen // ycItems.push_back(ycItem); vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d(0x%04x): val:%-.4f OFlow: %d Valid: %d Blocked: %d", header->type, adr, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl); - pos += sizeof(SFP104); - } - } - break; - case 30: // Single-point information with time tag CP56Time2a 带CP56时标的单点信息 - pos = sizeof(ST_ASDU_HEADER); - while (pos < len) - { - SP104_T *ps = (SP104_T*)&msgbuf[pos]; - adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; - CP56Time t56(ps->time); - char buf[32]; - t56.GetTimeString(buf, sizeof(buf)); - bSetPointTableValueYX(ps->siq.spi, adr); + pos += sizeof(SFP104); + } + } + break; + case 30: // Single-point information with time tag CP56Time2a 带CP56时标的单点信息 + pos = sizeof(ST_ASDU_HEADER); + while (pos < len) + { + SP104_T *ps = (SP104_T*)&msgbuf[pos]; + adr = ps->addr2 << 16 | ps->addr1 << 8 | ps->addr0; + CP56Time t56(ps->time); + char buf[32]; + t56.GetTimeString(buf, sizeof(buf)); + bSetPointTableValueYX(pIecCtrl, ps->siq.spi, adr); /* ycItem.stype = 1; @@ -1880,19 +2136,19 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItems.push_back(ycItem); */ - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d time:%s", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl, buf); - pos += sizeof(SP104_T); - } - if (cause == 3) SendMsgFormatS(sendno); // 突发上送之后发送S帧确认 - break; - case 36: // Measure value, short float point value w/CP56Time2a 带CP56时标的短浮点测量值 - pos = sizeof(ST_ASDU_HEADER); - while (pos < len) - { - SFP104_T *pf = (SFP104_T*)&msgbuf[pos]; - adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; - float *val = (float*)&pf->val[0]; - bSetPointTableValueYC(*val, adr); + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SP_%d: val:%d Valid: %d Blocked: %d time:%s", header->type, adr, ps->siq.spi, ps->siq.iv, ps->siq.bl, buf); + pos += sizeof(SP104_T); + } + if (cause == 3) SendMsgFormatS(pIecCtrl, sendno); // 突发上送之后发送S帧确认 + break; + case 36: // Measure value, short float point value w/CP56Time2a 带CP56时标的短浮点测量值 + pos = sizeof(ST_ASDU_HEADER); + while (pos < len) + { + SFP104_T *pf = (SFP104_T*)&msgbuf[pos]; + adr = pf->addr2 << 16 | pf->addr1 << 8 | pf->addr0; + float *val = (float*)&pf->val[0]; + bSetPointTableValueYC(*val, adr); CP56Time t56(pf->time); @@ -1902,41 +2158,41 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen ycItem.fval = *val; // ycItems.push_back(ycItem); - char buf[32]; - t56.GetTimeString(buf, sizeof(buf)); - vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d: val:%-.4f OFlow: %d Valid: %d Blocked: %d time:%s", header->type, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl, buf); - pos += sizeof(SFP104_T); - } - break; - case 45: - if (cause == 7 && !g_IecCtrl.is_yk_ack) // 收到遥控返校 - { - vYaoKongExe(msgbuf, len);// 遥控执行 - g_IecCtrl.is_yk_ack = true; - } - else if (cause == 7 && g_IecCtrl.is_yk_ack) - { - vYaoKongUnexe(msgbuf, len); // 遥控撤销 - g_IecCtrl.is_yk_ack = false; - } - break; - case 70: //站端初始化结束 - pos = sizeof(ST_ASDU_HEADER); // 跳过ASDU的头,size=6byte - idx = 0; - while (pos < len) - { - memcpy(&stObj[idx].objaddr, msgbuf + pos, 3); // 信息对象地址,3字节 - stObj[idx].objaddr = ntohi(stObj[idx].objaddr); // 转高低位 - pos += 3; - if (pos >= len) break; - stObj[idx].objval = (msgbuf[pos] & 0xff); // 对象值, 0:电源合 1:电源分 - idx++; - pos++; - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "End of Initialization"); - break; - case 100: // 总召唤命令 - if (cause == 7) // 激活确认 + char buf[32]; + t56.GetTimeString(buf, sizeof(buf)); + vPrtLogMsg(LOG_DEBUG, RET_OK, "type=%d SFP_%d: val:%-.4f OFlow: %d Valid: %d Blocked: %d time:%s", header->type, adr, *val, pf->qds.ov, pf->qds.iv, pf->qds.bl, buf); + pos += sizeof(SFP104_T); + } + break; + case 45: + if (cause == 7 && !g_IecCtrl.is_yk_ack) // 收到遥控返校 + { + vYaoKongExe(pIecCtrl, msgbuf, len);// 遥控执行 + g_IecCtrl.is_yk_ack = true; + } + else if (cause == 7 && g_IecCtrl.is_yk_ack) + { + vYaoKongUnexe(pIecCtrl, msgbuf, len); // 遥控撤销 + g_IecCtrl.is_yk_ack = false; + } + break; + case 70: //站端初始化结束 + pos = sizeof(ST_ASDU_HEADER); // 跳过ASDU的头,size=6byte + idx = 0; + while (pos < len) + { + memcpy(&stObj[idx].objaddr, msgbuf + pos, 3); // 信息对象地址,3字节 + stObj[idx].objaddr = ntohi(stObj[idx].objaddr); // 转高低位 + pos += 3; + if (pos >= len) break; + stObj[idx].objval = (msgbuf[pos] & 0xff); // 对象值, 0:电源合 1:电源分 + idx++; + pos++; + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "End of Initialization"); + break; + case 100: // 总召唤命令 + if (cause == 7) // 激活确认 { if (g_TConfig.shouldParseBusiData() != 0) { @@ -1944,121 +2200,123 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen } vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Confirmation, %d.", msgbuf[9] - 20); } - else if (cause == 10) // 激活结束 - { - g_IecCtrl.time_action = ts; // time(NULL); - // SendMsgFormatS(sendno); // 总召唤结束发送S帧确认 + else if (cause == 10) // 激活结束 + { + pIecCtrl->time_action = ts; // time(NULL); + // SendMsgFormatS(sendno); // 总召唤结束发送S帧确认 if (g_TConfig.shouldParseBusiData() != 0) { ResetAllCachedDeviceData(); } - vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Termination, %d", msgbuf[9] - 20); - } - else - vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Command:%d ,Unknown.", msgbuf[9] - 20); - break; - default: - vPrtLogMsg(LOG_WARNG, RET_OK, "Not Implemented!,type=%d", header->type); - break; - } + vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Termination, %d", msgbuf[9] - 20); + } + else + vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Command:%d ,Unknown.", msgbuf[9] - 20); + break; + default: + vPrtLogMsg(LOG_WARNG, RET_OK, "Not Implemented!,type=%d", header->type); + break; + } // if (!ycItems.empty()) { // bSetPointTableValueYC(ycItems); } - return RET_OK; + return RET_OK; } // 发送召唤激活 -int SendMsgFormatIAction(unsigned char cmd) +int SendMsgFormatIAction(ST_IEC104_CTRL* pIecCtrl, unsigned char cmd) { - int iRet = -1; - ST_IEC_APDU stPack; - - if (g_Tcp.tcpIsConnected(g_IecCtrl.sockid)) - { - memset(&stPack, 0x00, sizeof(ST_IEC_APDU)); - stPack.apci.start = 0x68; - stPack.apci.len = 0x0e; - stPack.apci.cntl1 = 0; // g_IecCtrl.usSendNo & 0xFF; - stPack.apci.cntl2 = 0;// (g_IecCtrl.usSendNo >> 8) & 0xFF; - stPack.apci.cntl3 = g_IecCtrl.usRecvNo & 0xFE; - stPack.apci.cntl4 = (g_IecCtrl.usRecvNo >> 8) & 0xFF; - stPack.asdu.header.type = cmd; - stPack.asdu.header.qual = 0x01; - stPack.asdu.header.tx_cause1 = 0x06; - stPack.asdu.header.tx_cause2 = 0x00; - stPack.asdu.header.commom_asdu1 = (g_iec_conf.iec_global_addr & 0xFF); - stPack.asdu.header.commom_asdu2 = (g_iec_conf.iec_global_addr >> 8) & 0xFF; - stPack.asdu.data[3] = 0x14; // 全召 + int iRet = -1; + ST_IEC_APDU stPack; + + if (g_Tcp.tcpIsConnected(pIecCtrl->sockid)) + { + memset(&stPack, 0x00, sizeof(ST_IEC_APDU)); + stPack.apci.start = 0x68; + stPack.apci.len = 0x0e; + stPack.apci.cntl1 = 0; // g_IecCtrl.usSendNo & 0xFF; + stPack.apci.cntl2 = 0;// (g_IecCtrl.usSendNo >> 8) & 0xFF; + stPack.apci.cntl3 = pIecCtrl->usRecvNo & 0xFE; + stPack.apci.cntl4 = (pIecCtrl->usRecvNo >> 8) & 0xFF; + stPack.asdu.header.type = cmd; + stPack.asdu.header.qual = 0x01; + stPack.asdu.header.tx_cause1 = 0x06; + stPack.asdu.header.tx_cause2 = 0x00; + stPack.asdu.header.commom_asdu1 = (g_iec_conf.iec_global_addr & 0xFF); + stPack.asdu.header.commom_asdu2 = (g_iec_conf.iec_global_addr >> 8) & 0xFF; + stPack.asdu.data[3] = 0x14; // 全召 #ifndef _WIN32 - iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&stPack, stPack.apci.len + 2, g_IecCtrl.pipeFds[0]); + iRet = g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&stPack, stPack.apci.len + 2, g_IecCtrl.pipeFds[0]); #else - iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&stPack, stPack.apci.len + 2, -1); + iRet = g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&stPack, stPack.apci.len + 2, -1); #endif - if (iRet == ErrException) - { - vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", g_IecCtrl.sockid, strerror(errno)); - g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, MAX_SBUFF_TCP); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; - } - - g_IecCtrl.time_action = -1; // 总召间隔时间更新 - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)&stPack, iRet); - } - return iRet; + if (iRet == ErrException) + { + vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", pIecCtrl->sockid, strerror(errno)); + g_Tcp.clear_tcp_buffer(pIecCtrl->sockid, MAX_SBUFF_TCP); + // g_Tcp.tcpCloseSocket(pIecCtrl->sockid); + pIecCtrl->isConnect = false; + CloseSocket(pIecCtrl->sockid); + return iRet; + } + + pIecCtrl->time_action = -1; // 总召间隔时间更新 + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_SEND, (unsigned char*)&stPack, iRet); + } + return iRet; } -void DecodeMsgFormatU(ST_APCI *p) +void DecodeMsgFormatU(ST_IEC104_CTRL* pIecCtrl, ST_APCI *p) { - switch (p->cntl1 & 0xfc) // 判断是否是U帧 - { - case CMD_STARTDT: // U启动 - SendMsgFormatU(CMD_STARTC); - break; - case CMD_STOPDT: // U停止 - SendMsgFormatU(CMD_STOPC); - break; - case CMD_TESTFR: // && !this->GetIsResponseUTest()) // U测试 - SendMsgFormatU(CMD_TESTC); - break; - case 0x08: // 启动确认位:=1 + switch (p->cntl1 & 0xfc) // 判断是否是U帧 + { + case CMD_STARTDT: // U启动 + SendMsgFormatU(pIecCtrl, CMD_STARTC); + break; + case CMD_STOPDT: // U停止 + SendMsgFormatU(pIecCtrl, CMD_STOPC); + break; + case CMD_TESTFR: // && !this->GetIsResponseUTest()) // U测试 + SendMsgFormatU(pIecCtrl, CMD_TESTC); + break; + case 0x08: // 启动确认位:=1 vPrtLogMsg(LOG_DEBUG, RET_OK, "Send Activation"); - SendMsgFormatIAction(CMD_CTL_64H); // 发送总召激活 - break; - default: - break; - } + SendMsgFormatIAction(pIecCtrl, CMD_CTL_64H); // 发送总召激活 + break; + default: + break; + } } // S-Formar message decodification S格式帧解码 -void DecodeMsgFormatS(unsigned char *msgbuf, unsigned int len) +void DecodeMsgFormatS(ST_IEC104_CTRL* pIecCtrl, unsigned char *msgbuf, unsigned int len) { - int Index; - ST_IEC_APDU stPkg; - - memset(&stPkg, 0x00, sizeof(ST_IEC_APDU)); - - printf("\nFormatS"); - - Index = 0; - /* - NsIec104Struct.SendBuffer[0]=0x68; - NsIec104Struct.SendBuffer[1]=0x04; - NsIec104Struct.SendBuffer[2]=0x0b; - NsIec104Struct.SendBuffer[3]=0x00; - NsIec104Struct.SendBuffer[4]=0x00; - NsIec104Struct.SendBuffer[5]=0x00; - - NsIec104Struct.ReceiveHimNumber[0]=NsIec104Struct.ReceiveBuffer[2]; - NsIec104Struct.ReceiveHimNumber[1]=NsIec104Struct.ReceiveBuffer[3]; - - if((NsIec104Struct.SendLength = send(NsIec104Struct.NsNewSocketId,&NsIec104Struct.SendBuffer[0],6,0x0)) < 0) - { - perror ("Client Write Error"); - } - printf("\nwrite=%d",NsIec104Struct.SendLength); - */ + int Index; + ST_IEC_APDU stPkg; + + memset(&stPkg, 0x00, sizeof(ST_IEC_APDU)); + + printf("\nFormatS"); + + Index = 0; + /* + NsIec104Struct.SendBuffer[0]=0x68; + NsIec104Struct.SendBuffer[1]=0x04; + NsIec104Struct.SendBuffer[2]=0x0b; + NsIec104Struct.SendBuffer[3]=0x00; + NsIec104Struct.SendBuffer[4]=0x00; + NsIec104Struct.SendBuffer[5]=0x00; + + NsIec104Struct.ReceiveHimNumber[0]=NsIec104Struct.ReceiveBuffer[2]; + NsIec104Struct.ReceiveHimNumber[1]=NsIec104Struct.ReceiveBuffer[3]; + + if((NsIec104Struct.SendLength = send(NsIec104Struct.NsNewSocketId,&NsIec104Struct.SendBuffer[0],6,0x0)) < 0) + { + perror ("Client Write Error"); + } + printf("\nwrite=%d",NsIec104Struct.SendLength); + */ } /*************************************************************************** ** function name : thread_parser_proc @@ -2068,73 +2326,87 @@ void DecodeMsgFormatS(unsigned char *msgbuf, unsigned int len) ***************************************************************************/ void * thread_parser_proc(void * arg) { - int len = 0, j = 0; - ST_RECVPKG pData; - - vPrtLogMsg(LOG_DEBUG, 0, "thread_parser_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - memset(&pData, 0x00, sizeof(ST_RECVPKG)); - mutex_lock(g_list_pack_mutex); - if (g_list_pack.empty() || g_list_pack.size() <= 0) { - mutex_unlock(g_list_pack_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - memcpy(&pData, &(g_list_pack.back()), sizeof(ST_RECVPKG)); // 由尾取出 - g_list_pack.pop_back(); // 由尾删除 - mutex_unlock(g_list_pack_mutex); - - if (pData.pszBuff == NULL) { - - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - - // 解析104报文 - if (pData.iLength >= MIN_APDU_LENGTH && (pData.pszBuff[0] & 0xff) == CMD_START_HEAD) // 0x68H - { - ST_APCI *pstAPCI = (ST_APCI*)pData.pszBuff; - g_IecCtrl.usISUType = (pstAPCI->cntl1 & 0x03); - g_IecCtrl.usSendNo = (pstAPCI->cntl2 << 8) | pstAPCI->cntl1; // 发送序号 - g_IecCtrl.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 - - if (g_IecCtrl.usISUType == 0 || g_IecCtrl.usISUType == 2) // I Format package - { - g_IecCtrl.timer_S_Ackflag = false; // 收到I格式帧的时候置为false, 超时的时候置为true. - g_IecCtrl.RxCounter = g_IecCtrl.usSendNo++; - g_IecCtrl.LastAckTx = g_IecCtrl.usRecvNo; - SendMsgFormatS(pData.usSendNo); // 应答 - DecodeMsgFormatI(pData.pszBuff + sizeof(ST_APCI), pData.iLength - sizeof(ST_APCI), pData.usSendNo); // 解析报文 - } - else if (g_IecCtrl.usISUType == 1) // S Format package - { - //DecodeMsgFormatS(pData.pszBuff + sizeof(ST_APCI), pData.iLength - sizeof(ST_APCI)); - } - else if (g_IecCtrl.usISUType == 3) // U Format package - { - DecodeMsgFormatU(pstAPCI); // U Format package - g_IecCtrl.usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; - g_IecCtrl.LastAckTx = g_IecCtrl.usRecvNo; - } - g_IecCtrl.timer_U_Testflag = false; // 接收到I S U格式的帧都需要重置,表示t3内已经接收到报文 - } - free(pData.pszBuff); - pData.pszBuff = NULL; - } - return NULL; + // ST_IEC104_CTRL* pIecCtrl = (ST_IEC104_CTRL*)arg; + int len = 0, j = 0; + ST_RECVPKG pData; + + vPrtLogMsg(LOG_DEBUG, 0, "thread_parser_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); + memset(&pData, 0x00, sizeof(ST_RECVPKG)); + mutex_lock(g_list_pack_mutex); + if (g_list_pack.empty() || g_list_pack.size() <= 0) { + mutex_unlock(g_list_pack_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + memcpy(&pData, &(g_list_pack.back()), sizeof(ST_RECVPKG)); // 由尾取出 + g_list_pack.pop_back(); // 由尾删除 + mutex_unlock(g_list_pack_mutex); + + if (pData.pszBuff == NULL) { + + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + + // 解析104报文 + if (pData.iLength >= MIN_APDU_LENGTH && (pData.pszBuff[0] & 0xff) == CMD_START_HEAD) // 0x68H + { + ST_IEC104_CTRL* pIecCtrl = NULL; + mutex_lock(g_IecCtrl_mutex); + std::map::iterator it = g_IecCtrls.find(pData.sockid); + if (it != g_IecCtrls.end()) + { + pIecCtrl = &(it->second); + } + mutex_unlock(g_IecCtrl_mutex); + if (pIecCtrl == NULL) + { + continue; + } + + ST_APCI *pstAPCI = (ST_APCI*)pData.pszBuff; + pIecCtrl->usISUType = (pstAPCI->cntl1 & 0x03); + pIecCtrl->usSendNo = (pstAPCI->cntl2 << 8) | pstAPCI->cntl1; // 发送序号 + pIecCtrl->usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; // 接收序号 + + if (pIecCtrl->usISUType == 0 || pIecCtrl->usISUType == 2) // I Format package + { + pIecCtrl->timer_S_Ackflag = false; // 收到I格式帧的时候置为false, 超时的时候置为true. + pIecCtrl->RxCounter = pIecCtrl->usSendNo++; + pIecCtrl->LastAckTx = pIecCtrl->usRecvNo; + SendMsgFormatS(pIecCtrl, pData.usSendNo); // 应答 + DecodeMsgFormatI(pIecCtrl, pData.pszBuff + sizeof(ST_APCI), pData.iLength - sizeof(ST_APCI), pData.usSendNo); // 解析报文 + } + else if (pIecCtrl->usISUType == 1) // S Format package + { + //DecodeMsgFormatS(pData.pszBuff + sizeof(ST_APCI), pData.iLength - sizeof(ST_APCI)); + } + else if (pIecCtrl->usISUType == 3) // U Format package + { + DecodeMsgFormatU(pIecCtrl, pstAPCI); // U Format package + pIecCtrl->usRecvNo = (pstAPCI->cntl4 << 8) | pstAPCI->cntl3; + pIecCtrl->LastAckTx = g_IecCtrl.usRecvNo; + } + pIecCtrl->timer_U_Testflag = false; // 接收到I S U格式的帧都需要重置,表示t3内已经接收到报文 + } + free(pData.pszBuff); + pData.pszBuff = NULL; + } + return NULL; } // IEC原始数据入库 void dbSet_iec_origin(char pszSql[][256], int count) { - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) return; - vPrtLogMsg(LOG_DEBUG, RET_OK, "insert iec_origin_data start, cont: %d", count); - if (!pdbHandle->InsertRecordBitch(pszSql, count)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO iec_origin_data message failed."); - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "insert iec_origin_data complater, insert top cont: %d", count); + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) return; + vPrtLogMsg(LOG_DEBUG, RET_OK, "insert iec_origin_data start, cont: %d", count); + if (!pdbHandle->InsertRecordBitch(pszSql, count)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO iec_origin_data message failed."); + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "insert iec_origin_data complater, insert top cont: %d", count); } /*************************************************************************** ** function name : thread_origin_proc @@ -2144,72 +2416,72 @@ void dbSet_iec_origin(char pszSql[][256], int count) ***************************************************************************/ void * thread_origin_proc(void * arg) { - int count = 0, n = 0; - ST_IECPOINT_TABLE pData; - char szSql[512] = { 0 }, szWaringTime[32] = { 0 }; - MYSQL *pMySql = NULL; - vPrtLogMsg(LOG_DEBUG, 0, "thread_origin_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); - mutex_lock(g_list_origin_mutex); - count = g_list_origin.size(); - n = 0; - if (g_list_origin.empty() || g_list_origin.size() <= 0) { - mutex_unlock(g_list_origin_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - //if (time(NULL) - g_IecCtrl.last_yc_time <= g_iec_conf.save_internal) // 超过设定保存时间间隔时 - //{ - // g_list_origin.clear(); - // mutex_unlock(g_list_origin_mutex); - // _SLEEP(MAX_SLEEP_EMPTY * 10); - // continue; - //} - //g_IecCtrl.last_yc_time = time(NULL); - - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) { - mutex_unlock(g_list_origin_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 5); - continue; - } - pMySql = pdbHandle->GetIdleMySql(); - if (pMySql == NULL) { - mutex_unlock(g_list_origin_mutex); - vPrtLogMsg(LOG_WARNG, RET_FAIL, "GetIdleMySql handle failed."); - _SLEEP(MAX_SLEEP_EMPTY); - continue; - } - pdbHandle->dbAutoCommit(pMySql, false); - for (int n = 0; n < (count > 500 ? 500 : count); n++) - { - memcpy(&pData, &(g_list_origin.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 - g_list_origin.pop_back(); // 由尾删除 - memset(szSql, 0x00, sizeof(szSql)); - vTranHostTimeFmt(pData.dtime, szWaringTime); - if ((pData.stype & 0xff) == 1) // 遥信 - { - snprintf(szSql, sizeof(szSql), "INSERT into iec_origin_data(id, site_id, site_tree_id,system_code,d_time,state,stype,sadr,sadrval) " - "VALUES(guuid(), '%s','%s', '%s','%s', '%d', '%d', '%d', '%d')", - pData.site_id, pData.eqm_code, pData.sys_code, szWaringTime, pData.wstate, pData.stype, pData.sadr, pData.cval); - } - else { // 遥测 - snprintf(szSql, sizeof(szSql), "INSERT into iec_origin_data(id, site_id, site_tree_id,system_code,d_time,state,stype,sadr,sadrval) " - "VALUES(guuid(), '%s','%s', '%s','%s', '%d','%d', '%d', '%.4f')", - pData.site_id, pData.eqm_code, pData.sys_code, szWaringTime, pData.wstate, pData.stype, pData.sadr, pData.fval); - } - pdbHandle->AddInsertRecord(pMySql, szSql); - } - pdbHandle->dbCommit(pMySql); - pdbHandle->dbAutoCommit(pMySql, true); - pdbHandle->SetIdleMysql(pMySql); - mutex_unlock(g_list_origin_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - } - return NULL; + int count = 0, n = 0; + ST_IECPOINT_TABLE pData; + char szSql[512] = { 0 }, szWaringTime[32] = { 0 }; + MYSQL *pMySql = NULL; + vPrtLogMsg(LOG_DEBUG, 0, "thread_origin_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); + memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); + mutex_lock(g_list_origin_mutex); + count = g_list_origin.size(); + n = 0; + if (g_list_origin.empty() || g_list_origin.size() <= 0) { + mutex_unlock(g_list_origin_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + //if (time(NULL) - g_IecCtrl.last_yc_time <= g_iec_conf.save_internal) // 超过设定保存时间间隔时 + //{ + // g_list_origin.clear(); + // mutex_unlock(g_list_origin_mutex); + // _SLEEP(MAX_SLEEP_EMPTY * 10); + // continue; + //} + //g_IecCtrl.last_yc_time = time(NULL); + + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) { + mutex_unlock(g_list_origin_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 5); + continue; + } + pMySql = pdbHandle->GetIdleMySql(); + if (pMySql == NULL) { + mutex_unlock(g_list_origin_mutex); + vPrtLogMsg(LOG_WARNG, RET_FAIL, "GetIdleMySql handle failed."); + _SLEEP(MAX_SLEEP_EMPTY); + continue; + } + pdbHandle->dbAutoCommit(pMySql, false); + for (int n = 0; n < (count > 500 ? 500 : count); n++) + { + memcpy(&pData, &(g_list_origin.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 + g_list_origin.pop_back(); // 由尾删除 + memset(szSql, 0x00, sizeof(szSql)); + vTranHostTimeFmt(pData.dtime, szWaringTime); + if ((pData.stype & 0xff) == 1) // 遥信 + { + snprintf(szSql, sizeof(szSql), "INSERT into iec_origin_data(id, site_id, site_tree_id,system_code,d_time,state,stype,sadr,sadrval) " + "VALUES(guuid(), '%s','%s', '%s','%s', '%d', '%d', '%d', '%d')", + pData.site_id, pData.eqm_code, pData.sys_code, szWaringTime, pData.wstate, pData.stype, pData.sadr, pData.cval); + } + else { // 遥测 + snprintf(szSql, sizeof(szSql), "INSERT into iec_origin_data(id, site_id, site_tree_id,system_code,d_time,state,stype,sadr,sadrval) " + "VALUES(guuid(), '%s','%s', '%s','%s', '%d','%d', '%d', '%.4f')", + pData.site_id, pData.eqm_code, pData.sys_code, szWaringTime, pData.wstate, pData.stype, pData.sadr, pData.fval); + } + pdbHandle->AddInsertRecord(pMySql, szSql); + } + pdbHandle->dbCommit(pMySql); + pdbHandle->dbAutoCommit(pMySql, true); + pdbHandle->SetIdleMysql(pMySql); + mutex_unlock(g_list_origin_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + } + return NULL; } /*************************************************************************** @@ -2220,21 +2492,36 @@ void * thread_origin_proc(void * arg) ***************************************************************************/ void * thread_origin_proc_new(void * arg) { - int count = 0, n = 0; - IEC_OBJVAL_NEW pData; char szSql[512] = { 0 }, szWaringTime[32] = { 0 }; MYSQL *pMySql = NULL; - g_IecCtrl.last_origin_time = time(NULL); + list list_origin_new; + +#if 0 + pIecCtrl->last_origin_time = time(NULL); +#endif vPrtLogMsg(LOG_DEBUG, 0, "thread_origin_proc_new = %d startup...", GETTID()); while (g_Running) { pthread_testcancels(); - memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); + + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) { + _SLEEP(MAX_SLEEP_EMPTY * 5); + continue; + } + pMySql = pdbHandle->GetIdleMySql(); + if (pMySql == NULL) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "GetIdleMySql handle failed."); + _SLEEP(MAX_SLEEP_EMPTY); + continue; + } + mutex_lock(g_list_origin_mutex_new); - count = g_list_origin_new.size(); - n = 0; - if (g_list_origin_new.empty() || g_list_origin_new.size() <= 0) { - mutex_unlock(g_list_origin_mutex_new); + g_list_origin_new.swap(list_origin_new); + mutex_unlock(g_list_origin_mutex_new); + + if (list_origin_new.empty() || list_origin_new.size() <= 0) { + pdbHandle->SetIdleMysql(pMySql); _SLEEP(MAX_SLEEP_EMPTY * 10); continue; } @@ -2247,54 +2534,47 @@ void * thread_origin_proc_new(void * arg) //} //g_IecCtrl.last_yc_time = time(NULL); - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) { - mutex_unlock(g_list_origin_mutex_new); - _SLEEP(MAX_SLEEP_EMPTY * 5); - continue; - } - pMySql = pdbHandle->GetIdleMySql(); - if (pMySql == NULL) { - mutex_unlock(g_list_origin_mutex_new); - vPrtLogMsg(LOG_WARNG, RET_FAIL, "GetIdleMySql handle failed."); - _SLEEP(MAX_SLEEP_EMPTY); - continue; - } + pdbHandle->dbAutoCommit(pMySql, false); - for (int n = 0; n < (count > 500 ? 500 : count); n++) + for (list::iterator it = list_origin_new.begin(); it != list_origin_new.end(); ++it) { - memcpy(&pData, &(g_list_origin_new.back()), sizeof(IEC_OBJVAL_NEW)); // 由尾取出 - g_list_origin_new.pop_back(); // 由尾删除 memset(szSql, 0x00, sizeof(szSql)); - vTranHostTimeFmt(pData.dtime, szWaringTime); - if (pData.stype == 1) // 遥信 + vTranHostTimeFmt(it->dtime, szWaringTime); + if (it->stype == 1) // 遥信 { snprintf(szSql, sizeof(szSql), "INSERT INTO niec_origin_data(d_time,stype,sadr,ival) " "VALUES('%s', '%d', '%d', '%u')", - szWaringTime, pData.stype, pData.sadr, pData.ival); + szWaringTime, it->stype, it->sadr, it->ival); } else { // 遥测 snprintf(szSql, sizeof(szSql), "INSERT INTO niec_origin_data(d_time,stype,sadr,fval) " "VALUES('%s', '%d', '%d', '%.4f')", - szWaringTime, pData.stype, pData.sadr, pData.fval); + szWaringTime, it->stype, it->sadr, it->fval); } pdbHandle->AddInsertRecord(pMySql, szSql); + if (std::distance(list_origin_new.begin(), it) >= 500) + { + pdbHandle->dbCommit(pMySql); + } } pdbHandle->dbCommit(pMySql); pdbHandle->dbAutoCommit(pMySql, true); + list_origin_new.clear(); + +#if 0 time_t now = time(NULL); - if (now - g_IecCtrl.last_origin_time >= g_iec_conf.orgin_data_save_internal) // 超过设定保存时间间隔时 + if (now - pIecCtrl->last_origin_time >= g_iec_conf.orgin_data_save_internal) // 超过设定保存时间间隔时 { - g_IecCtrl.last_origin_time = now; + pIecCtrl->last_origin_time = now; memset(szSql, 0x00, sizeof(szSql)); vTranHostTimeFmt((now - g_iec_conf.orgin_data_save_internal), szWaringTime); snprintf(szSql, sizeof(szSql), "DELETE FROM niec_origin_data WHERE d_time<'%s' ", szWaringTime); pdbHandle->AddInsertRecord(pMySql, szSql); } +#endif pdbHandle->SetIdleMysql(pMySql); - mutex_unlock(g_list_origin_mutex_new); _SLEEP(MAX_SLEEP_EMPTY * 10); } return NULL; @@ -2326,7 +2606,7 @@ void * thread_busi_data_proc(void * arg) _SLEEP(MAX_SLEEP_EMPTY * 10); continue; } - + CDBMySQL *pdbHandle = CDBMySQL::Instance(); if (!pdbHandle) { mutex_unlock(g_list_busi_data_mutex); @@ -2366,101 +2646,101 @@ void * thread_busi_data_proc(void * arg) ***************************************************************************/ int iGetSadrMatchRecord(unsigned int sadr, ST_SADR_MATCH &adrList) { - if(sadr <= 0) return 0 ; - map::iterator m_pIter; - mutex_lock(g_map_sadr_mutex); - m_pIter = g_map_sadr.find(sadr); - if (m_pIter == g_map_sadr.end()) - { - mutex_unlock(g_map_sadr_mutex); - return 0; - } - adrList.psadr = (ST_MATCH_LIST*)calloc(m_pIter->second.count, sizeof(ST_MATCH_LIST)); - if (adrList.psadr == NULL) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "calloc failed."); - mutex_unlock(g_map_sadr_mutex); - return 0; - } - adrList.count = (m_pIter->second).count; - adrList.eqm_type = (m_pIter->second).eqm_type; - for (int i = 0; i < (int)adrList.count; i++) - { - adrList.psadr[i].btype = (m_pIter->second).psadr[i].btype; - adrList.psadr[i].group = (m_pIter->second).psadr[i].group; - adrList.psadr[i].sadr = (m_pIter->second).psadr[i].sadr; - } - mutex_unlock(g_map_sadr_mutex); - - return adrList.count; + if (sadr <= 0) return 0; + map::iterator m_pIter; + mutex_lock(g_map_sadr_mutex); + m_pIter = g_map_sadr.find(sadr); + if (m_pIter == g_map_sadr.end()) + { + mutex_unlock(g_map_sadr_mutex); + return 0; + } + adrList.psadr = (ST_MATCH_LIST*)calloc(m_pIter->second.count, sizeof(ST_MATCH_LIST)); + if (adrList.psadr == NULL) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "calloc failed."); + mutex_unlock(g_map_sadr_mutex); + return 0; + } + adrList.count = (m_pIter->second).count; + adrList.eqm_type = (m_pIter->second).eqm_type; + for (int i = 0; i < (int)adrList.count; i++) + { + adrList.psadr[i].btype = (m_pIter->second).psadr[i].btype; + adrList.psadr[i].group = (m_pIter->second).psadr[i].group; + adrList.psadr[i].sadr = (m_pIter->second).psadr[i].sadr; + } + mutex_unlock(g_map_sadr_mutex); + + return adrList.count; } // 获取指定地址关系的组号记录 static bool bGetSadrMatchRecord(int gorup, ST_SADR_MATCH &adrList) { - map::iterator m_pIter; - mutex_lock(g_map_sadr_mutex); - - for (m_pIter = g_map_sadr.begin(); m_pIter != g_map_sadr.end(); m_pIter++) - { - for (int i = 0; i < (int)(m_pIter->second).count; i++) - { - if ((int)((m_pIter->second).psadr[i].group) == gorup) - { - adrList.psadr = (ST_MATCH_LIST*)calloc((m_pIter->second).count, sizeof(ST_MATCH_LIST)); - if (adrList.psadr == NULL) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "calloc failed."); - mutex_unlock(g_map_sadr_mutex); - return false; - } - adrList.count = (m_pIter->second).count; - adrList.eqm_type = (m_pIter->second).eqm_type; - for (int i = 0; i < (int)adrList.count; i++) - { - adrList.psadr[i].btype = (m_pIter->second).psadr[i].btype; - adrList.psadr[i].group = (m_pIter->second).psadr[i].group; - adrList.psadr[i].sadr = (m_pIter->second).psadr[i].sadr; - } - mutex_unlock(g_map_sadr_mutex); - return true; - } - } - } - mutex_unlock(g_map_sadr_mutex); - return false; + map::iterator m_pIter; + mutex_lock(g_map_sadr_mutex); + + for (m_pIter = g_map_sadr.begin(); m_pIter != g_map_sadr.end(); m_pIter++) + { + for (int i = 0; i < (int)(m_pIter->second).count; i++) + { + if ((int)((m_pIter->second).psadr[i].group) == gorup) + { + adrList.psadr = (ST_MATCH_LIST*)calloc((m_pIter->second).count, sizeof(ST_MATCH_LIST)); + if (adrList.psadr == NULL) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "calloc failed."); + mutex_unlock(g_map_sadr_mutex); + return false; + } + adrList.count = (m_pIter->second).count; + adrList.eqm_type = (m_pIter->second).eqm_type; + for (int i = 0; i < (int)adrList.count; i++) + { + adrList.psadr[i].btype = (m_pIter->second).psadr[i].btype; + adrList.psadr[i].group = (m_pIter->second).psadr[i].group; + adrList.psadr[i].sadr = (m_pIter->second).psadr[i].sadr; + } + mutex_unlock(g_map_sadr_mutex); + return true; + } + } + } + mutex_unlock(g_map_sadr_mutex); + return false; } // 提取数据 static bool bGetValueBySadr(ST_IECPOINT_TABLE &stPoint) { - map::iterator m_pIter; - mutex_lock(g_map_iec_mutex); - m_pIter = g_map_iec.find(stPoint.sadr); - if (m_pIter == g_map_iec.end()) - { - mutex_unlock(g_map_iec_mutex); - return false; - } - memcpy(&stPoint, &m_pIter->second, sizeof(ST_IECPOINT_TABLE)); - mutex_unlock(g_map_iec_mutex); - return true; + map::iterator m_pIter; + mutex_lock(g_map_iec_mutex); + m_pIter = g_map_iec.find(stPoint.sadr); + if (m_pIter == g_map_iec.end()) + { + mutex_unlock(g_map_iec_mutex); + return false; + } + memcpy(&stPoint, &m_pIter->second, sizeof(ST_IECPOINT_TABLE)); + mutex_unlock(g_map_iec_mutex); + return true; } //初始化运行工况数据 void initRunState(ST_IEC_BYQREAD_TABLE &stRunState, int dInitValue) { - stRunState.dcurJkyl[0] = dInitValue; // 冷却水进口压力值 - stRunState.dcurCkyl[0] = dInitValue; // 冷却水出口压力值 - stRunState.dCoolWaterTempEntry[0] = dInitValue; // 冷却水进口温度 - stRunState.dCoolWaterTempOuter[0] = dInitValue; // 冷却水出口温度 - - stRunState.dOilPressEntry[0] = dInitValue; // 变压器油进口油压力(MPa) - stRunState.dOilPressOuter[0] = dInitValue; // 变压器油出口油压力(MPa) - stRunState.dOilTempEntry[0] = dInitValue; // 变压器油进口温度 - stRunState.dOilTempOuter[0] = dInitValue; // 变压器油出口温度 - - stRunState.dOilTemperature[0] = dInitValue; //主变本体油温点位 - stRunState.dOilPosition[0] = dInitValue; //主变本体油位点位 - stRunState.dOilTopTemp[0] = dInitValue; //主变顶层油温点位 - stRunState.dOilPillowLevel[0] = dInitValue; //主变油枕油位点位 - stRunState.dWindingTemp[0] = dInitValue; //主变绕组温度点位 + stRunState.dcurJkyl[0] = dInitValue; // 冷却水进口压力值 + stRunState.dcurCkyl[0] = dInitValue; // 冷却水出口压力值 + stRunState.dCoolWaterTempEntry[0] = dInitValue; // 冷却水进口温度 + stRunState.dCoolWaterTempOuter[0] = dInitValue; // 冷却水出口温度 + + stRunState.dOilPressEntry[0] = dInitValue; // 变压器油进口油压力(MPa) + stRunState.dOilPressOuter[0] = dInitValue; // 变压器油出口油压力(MPa) + stRunState.dOilTempEntry[0] = dInitValue; // 变压器油进口温度 + stRunState.dOilTempOuter[0] = dInitValue; // 变压器油出口温度 + + stRunState.dOilTemperature[0] = dInitValue; //主变本体油温点位 + stRunState.dOilPosition[0] = dInitValue; //主变本体油位点位 + stRunState.dOilTopTemp[0] = dInitValue; //主变顶层油温点位 + stRunState.dOilPillowLevel[0] = dInitValue; //主变油枕油位点位 + stRunState.dWindingTemp[0] = dInitValue; //主变绕组温度点位 } //// 运行工况数据有效性转换 //char * double2String(double value, double dInitValue, char *pStr, int iStrLen) @@ -2472,237 +2752,241 @@ void initRunState(ST_IEC_BYQREAD_TABLE &stRunState, int dInitValue) void calcHigthVolCurr(double &vol, double &curr) { - double dvol = vol; - double dcurr = curr; - vPrtLogMsg(LOG_WARNG, RET_OK, "vol = %.4f cur=%.4f", vol,curr); - //double dHvol = ((525000 * 1.732) / 3); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 - double dHvol = (525000 / 1.732); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 - curr = (dvol*dcurr) / dHvol; // 高压侧电流=(低压侧单相低压*低压侧单相电流)/高压侧电压 - vol = dHvol; + double dvol = vol; + double dcurr = curr; + vPrtLogMsg(LOG_WARNG, RET_OK, "vol = %.4f cur=%.4f", vol, curr); + //double dHvol = ((525000 * 1.732) / 3); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 + double dHvol = (525000 / 1.732); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 + curr = (dvol*dcurr) / dHvol; // 高压侧电流=(低压侧单相低压*低压侧单相电流)/高压侧电压 + vol = dHvol; } // 组织变压器评测数据,iec_bydwork_param -static void vBuildByqWorkParam(ST_IECPOINT_TABLE &stIec,ST_SADR_MATCH &adrList) +static void vBuildByqWorkParam( ST_IECPOINT_TABLE &stIec, ST_SADR_MATCH &adrList) { - double dInitValue = -9999.0f; - ST_IEC_BYQWORK_TABLE stWork; - ST_IEC_BYQREAD_TABLE stRunState; - ST_IEC_GISBREAK_TABLE stGis; - // 数据入库 - char szSql[DEF_BUFFER_1K] = { 0 }; - char sTime[24] = { 0 }, eTime[24] = { 0 }; - - memset(&stWork, 0x00, sizeof(ST_IEC_BYQWORK_TABLE)); - memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE)); - memset(&stRunState, 0x00, sizeof(ST_IEC_BYQREAD_TABLE)); - initRunState(stRunState, 0x00); - - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) return; - int group = 0; - time_t st = 0; +#if 0 + double dInitValue = -9999.0f; + ST_IEC_BYQWORK_TABLE stWork; + ST_IEC_BYQREAD_TABLE stRunState; + ST_IEC_GISBREAK_TABLE stGis; + // 数据入库 + char szSql[DEF_BUFFER_1K] = { 0 }; + char sTime[24] = { 0 }, eTime[24] = { 0 }; + + memset(&stWork, 0x00, sizeof(ST_IEC_BYQWORK_TABLE)); + memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE)); + memset(&stRunState, 0x00, sizeof(ST_IEC_BYQREAD_TABLE)); + initRunState(stRunState, 0x00); + + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) return; + int group = 0; + time_t st = 0; //vPrtLogMsg(LOG_WARNG, RET_OK, "---------adrList.count:%d----------",adrList.count); - for (int i = 0; i < (int)adrList.count; i++) - { - memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); - if (adrList.psadr[i].sadr <= 0) continue; // 0时,表示104配置文件中没有此点表地址 - stIec.sadr = adrList.psadr[i].sadr ; - if (false == bGetValueBySadr(stIec)) continue; - if (adrList.psadr[i].sadr == stIec.sadr) - { - group = adrList.psadr[i].group; - switch (group) - { - case 1: // 主变高压侧电流电压组 - case 2: // 主变低压侧电流电压组 - if (adrList.psadr[i].btype == 1) stWork.current = stIec.fval; - else if (adrList.psadr[i].btype == 2) stWork.voltage = stIec.fval; - if(strlen((const char *)stWork.eqm_code) <=0) - strncpy((char *)stWork.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); - if (strlen((const char *)stWork.site_id) <= 0) - strncpy((char *)stWork.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); - if (strlen((const char *)stWork.system_code) <= 0) - strncpy((char *)stWork.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); - stWork.state = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态 - if (st <= 0) - { - st = GetDevTimeStat(stIec.sys_code, &stWork.state) ; - vTranHostTimeFmt(st, sTime); - } - vTranHostTimeFmt(st, sTime); - g_IecCtrl.stime = time(NULL); - vTranHostTimeFmt(g_IecCtrl.stime, eTime); + for (int i = 0; i < (int)adrList.count; i++) + { + memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); + if (adrList.psadr[i].sadr <= 0) continue; // 0时,表示104配置文件中没有此点表地址 + stIec.sadr = adrList.psadr[i].sadr; + if (false == bGetValueBySadr(stIec)) continue; + if (adrList.psadr[i].sadr == stIec.sadr) + { + group = adrList.psadr[i].group; + switch (group) + { + case 1: // 主变高压侧电流电压组 + case 2: // 主变低压侧电流电压组 + if (adrList.psadr[i].btype == 1) stWork.current = stIec.fval; + else if (adrList.psadr[i].btype == 2) stWork.voltage = stIec.fval; + if (strlen((const char *)stWork.eqm_code) <= 0) + strncpy((char *)stWork.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); + if (strlen((const char *)stWork.site_id) <= 0) + strncpy((char *)stWork.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); + if (strlen((const char *)stWork.system_code) <= 0) + strncpy((char *)stWork.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); + stWork.state = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态 + if (st <= 0) + { + st = GetDevTimeStat(stIec.sys_code, &stWork.state); + vTranHostTimeFmt(st, sTime); + } + vTranHostTimeFmt(st, sTime); + g_IecCtrl.stime = time(NULL); + vTranHostTimeFmt(g_IecCtrl.stime, eTime); #ifdef _DEF_HMF_VOLTAGE - // 根据低压侧的电压电流及额定高压侧电压,计算高压侧电流 - if (((stWork.state & 0xff) == 1) && (stWork.voltage >0 && stWork.current > 0)) { - calcHigthVolCurr(stWork.voltage, stWork.current); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 - } + // 根据低压侧的电压电流及额定高压侧电压,计算高压侧电流 + if (((stWork.state & 0xff) == 1) && (stWork.voltage > 0 && stWork.current > 0)) { + calcHigthVolCurr(stWork.voltage, stWork.current); // 高压侧电压=((额定电压*根号3)/3)=单相的电压值 + } #endif - //if (g_IecCtrl.stime > 0) { - // if (strlen(sTime) <= 0) - // { - // vTranHostTimeFmt(g_IecCtrl.stime, sTime); - // g_IecCtrl.stime = time(NULL); - // vTranHostTimeFmt(g_IecCtrl.stime, eTime); - // } - //} - //else { - // g_IecCtrl.stime = time(NULL); - // if (strlen(sTime) <= 0) vTranHostTimeFmt(g_IecCtrl.stime, sTime); - // vTranHostTimeFmt(time(NULL), eTime); - //} - stWork.is_fault = cGetByqDeviceFaultState(stIec.eqm_code); // 获取事故状态 - break; - case 3: // 主变运行工况组 - if (adrList.psadr[i].btype == 1) sprintf(stRunState.dcurJkyl,"%.4f",stIec.fval); // 进口水压力 - else if (adrList.psadr[i].btype == 2) sprintf(stRunState.dcurCkyl, "%.4f", stIec.fval); // 出口水压力 - else if (adrList.psadr[i].btype == 3) sprintf(stRunState.dOilPosition, "%.4f", stIec.fval); // 主变油位数 - else if (adrList.psadr[i].btype == 4) sprintf(stRunState.dOilTemperature, "%.4f", stIec.fval); // 主变油温数 - - else if (adrList.psadr[i].btype == 5) sprintf(stRunState.dCoolWaterTempEntry,"%.4f",stIec.fval); // 进口水温度 - else if (adrList.psadr[i].btype == 6) sprintf(stRunState.dCoolWaterTempOuter, "%.4f", stIec.fval); // 出口水温度 - else if (adrList.psadr[i].btype == 7) sprintf(stRunState.dOilPressEntry, "%.4f", stIec.fval); // 进口油压力 - else if (adrList.psadr[i].btype == 8) sprintf(stRunState.dOilPressOuter, "%.4f", stIec.fval); // 出口油压力 - - else if (adrList.psadr[i].btype == 9) sprintf(stRunState.dOilTempEntry, "%.4f", stIec.fval); // 进口油温度 - else if (adrList.psadr[i].btype == 10) sprintf(stRunState.dOilTempOuter, "%.4f", stIec.fval); // 出口油温度 - else if (adrList.psadr[i].btype == 11) sprintf(stRunState.dOilPillowLevel, "%.4f", stIec.fval);// 油枕油位 - else if (adrList.psadr[i].btype == 12) sprintf(stRunState.dOilTopTemp, "%.4f", stIec.fval); // 顶层油温度 - else if (adrList.psadr[i].btype == 13) sprintf(stRunState.dWindingTemp, "%.4f", stIec.fval); // 绕组温度 - - if (stRunState.chkTime <= 0) stRunState.chkTime = stIec.dtime; - else stRunState.chkTime = (stRunState.chkTime < stIec.dtime ? stRunState.chkTime : stIec.dtime); - - if (strlen((const char *)stRunState.eqm_code) <= 0) - strncpy((char *)stRunState.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); - if (strlen((const char *)stRunState.site_id) <= 0) - strncpy((char *)stRunState.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); - if (strlen((const char *)stRunState.system_code) <= 0) - strncpy((char *)stRunState.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); - stRunState.wstate = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态; - break; - case 4: // 断路器电流电压组 - if (adrList.psadr[i].btype == 1) stGis.abort_current = stIec.fval; // 断开电流 - else if (adrList.psadr[i].btype == 2) stGis.abort_voltage = stIec.fval; // 断开电压 - if (strlen((const char *)stGis.eqm_code) <= 0) - strncpy((char *)stGis.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); - if (strlen((const char *)stGis.site_id) <= 0) - strncpy((char *)stGis.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); - if (strlen((const char *)stGis.system_code) <= 0) - strncpy((char *)stGis.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); - if (stGis.d_time <= 0) stGis.d_time = stIec.dtime; - else stGis.d_time = (stGis.d_time < stIec.dtime ? stGis.d_time : stIec.dtime); - // stGis.wstate = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态; - stGis.wstate = cGetCurrentWorkState(stIec.eqm_code); - stGis.faild_rate = 0; - stGis.is_fault = stIec.bfault; - stGis.is_close = 1; // getGisOpenCloseState(stIec.site_id, stIec.eqm_code); - break; - default:; - } - } - } - // for test - //vGetHostTimeFmtBeforBay(sTime, 1); - //_SLEEP(1000); - //vGetHostTimeFmtBeforBay(eTime, 1); - // - switch (group) - { - case 1: // 主变高压侧电流电压组 - case 2: // 主变低压侧电流电压组 - snprintf(szSql, sizeof(szSql), "INSERT INTO iec_bydwork_param(id,site_id,eqm_code,system_code,stype,start_time,stop_time," - "higth_voltage,higth_current, record_date, ins_date) " - "VALUES(guuid(),'%s', '%s','%s', '%d', '%s', '%s', %.4f, %.4f, SYSDATE(), SYSDATE())", - stWork.site_id, stWork.eqm_code, stWork.system_code, stWork.state, sTime, eTime, stWork.voltage, stWork.current); - vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_bydwork_param: %s", szSql); - break; - case 3: // 主变运行工况组 - // 原始数据入库 - vTranHostTimeFmt(stRunState.chkTime, sTime); - memset(szSql, 0x00, sizeof(szSql)); - snprintf(szSql, sizeof(szSql), - "INSERT INTO transformer_run_status(id, main_tree_id, system_code, work_status, d_time, oil_temperature, oil_position," - "cooling_entry_pressure, cooling_exit_pressure, coolingwater_inlet_temperature,coolingwater_outlet_temperature," - "circulating_oil_inlet_pressure,circulating_oil_outlet_pressure,top_oil_temperature,oilpillow_oillevel," - "winding_temperature,circulating_oil_inlet_temperature,circulating_oil_out_temperature,site_id) " - // "VALUES(guuid(),'%s','%s','%d','%s', '%.4f', '%.4f', '%.4f', '%.4f','%.4f', '%.4f', '%.4f', '%.4f','%.4f', '%.4f', '%.4f','%s')", - "VALUES(guuid(),'%s','%s','%d','%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s','%s', '%s', '%s','%s','%s','%s')", - stRunState.eqm_code, stRunState.system_code, stRunState.wstate, sTime, - stRunState.dOilTemperature, - stRunState.dOilPosition, - stRunState.dcurJkyl, - stRunState.dcurCkyl, - stRunState.dCoolWaterTempEntry, - stRunState.dCoolWaterTempOuter, - stRunState.dOilPressEntry, - stRunState.dOilPressOuter, - stRunState.dOilTopTemp, - stRunState.dOilPillowLevel, - stRunState.dWindingTemp, - stRunState.dOilTempEntry, - stRunState.dOilTempOuter, - stRunState.site_id); - vPrtLogMsg(LOG_DEBUG, RET_OK, "transformer_run_status: %s", szSql); - break; - case 4: // 断路器电流电压组 - memset(szSql, 0x00, sizeof(szSql)); - vTranHostTimeFmt(stGis.d_time, sTime); - snprintf(szSql, sizeof(szSql), "INSERT INTO iec_breaker_param(id,site_id,eqm_code,system_code,d_time,work_state,abort_current,abort_voltage,faild_rate," - "is_fault,is_break,ins_date) " - "VALUES(guuid(),'%s', '%s', '%s','%s','%d',%.4f, %.4f, %.4f, '%d', '%d',SYSDATE())", - stGis.site_id, stGis.eqm_code, stGis.system_code, sTime, stGis.wstate, stGis.abort_current, stGis.abort_voltage, stGis.faild_rate, - stGis.is_fault, stGis.is_close); - vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_breaker_param: %s", szSql); - break; - default:; - } - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql); - } + //if (g_IecCtrl.stime > 0) { + // if (strlen(sTime) <= 0) + // { + // vTranHostTimeFmt(g_IecCtrl.stime, sTime); + // g_IecCtrl.stime = time(NULL); + // vTranHostTimeFmt(g_IecCtrl.stime, eTime); + // } + //} + //else { + // g_IecCtrl.stime = time(NULL); + // if (strlen(sTime) <= 0) vTranHostTimeFmt(g_IecCtrl.stime, sTime); + // vTranHostTimeFmt(time(NULL), eTime); + //} + stWork.is_fault = cGetByqDeviceFaultState(stIec.eqm_code); // 获取事故状态 + break; + case 3: // 主变运行工况组 + if (adrList.psadr[i].btype == 1) sprintf(stRunState.dcurJkyl, "%.4f", stIec.fval); // 进口水压力 + else if (adrList.psadr[i].btype == 2) sprintf(stRunState.dcurCkyl, "%.4f", stIec.fval); // 出口水压力 + else if (adrList.psadr[i].btype == 3) sprintf(stRunState.dOilPosition, "%.4f", stIec.fval); // 主变油位数 + else if (adrList.psadr[i].btype == 4) sprintf(stRunState.dOilTemperature, "%.4f", stIec.fval); // 主变油温数 + + else if (adrList.psadr[i].btype == 5) sprintf(stRunState.dCoolWaterTempEntry, "%.4f", stIec.fval); // 进口水温度 + else if (adrList.psadr[i].btype == 6) sprintf(stRunState.dCoolWaterTempOuter, "%.4f", stIec.fval); // 出口水温度 + else if (adrList.psadr[i].btype == 7) sprintf(stRunState.dOilPressEntry, "%.4f", stIec.fval); // 进口油压力 + else if (adrList.psadr[i].btype == 8) sprintf(stRunState.dOilPressOuter, "%.4f", stIec.fval); // 出口油压力 + + else if (adrList.psadr[i].btype == 9) sprintf(stRunState.dOilTempEntry, "%.4f", stIec.fval); // 进口油温度 + else if (adrList.psadr[i].btype == 10) sprintf(stRunState.dOilTempOuter, "%.4f", stIec.fval); // 出口油温度 + else if (adrList.psadr[i].btype == 11) sprintf(stRunState.dOilPillowLevel, "%.4f", stIec.fval);// 油枕油位 + else if (adrList.psadr[i].btype == 12) sprintf(stRunState.dOilTopTemp, "%.4f", stIec.fval); // 顶层油温度 + else if (adrList.psadr[i].btype == 13) sprintf(stRunState.dWindingTemp, "%.4f", stIec.fval); // 绕组温度 + + if (stRunState.chkTime <= 0) stRunState.chkTime = stIec.dtime; + else stRunState.chkTime = (stRunState.chkTime < stIec.dtime ? stRunState.chkTime : stIec.dtime); + + if (strlen((const char *)stRunState.eqm_code) <= 0) + strncpy((char *)stRunState.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); + if (strlen((const char *)stRunState.site_id) <= 0) + strncpy((char *)stRunState.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); + if (strlen((const char *)stRunState.system_code) <= 0) + strncpy((char *)stRunState.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); + stRunState.wstate = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态; + break; + case 4: // 断路器电流电压组 + if (adrList.psadr[i].btype == 1) stGis.abort_current = stIec.fval; // 断开电流 + else if (adrList.psadr[i].btype == 2) stGis.abort_voltage = stIec.fval; // 断开电压 + if (strlen((const char *)stGis.eqm_code) <= 0) + strncpy((char *)stGis.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); + if (strlen((const char *)stGis.site_id) <= 0) + strncpy((char *)stGis.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); + if (strlen((const char *)stGis.system_code) <= 0) + strncpy((char *)stGis.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); + if (stGis.d_time <= 0) stGis.d_time = stIec.dtime; + else stGis.d_time = (stGis.d_time < stIec.dtime ? stGis.d_time : stIec.dtime); + // stGis.wstate = cGetByqDeviceState(stIec.eqm_code); // 获取工作状态; + stGis.wstate = cGetCurrentWorkState(stIec.eqm_code); + stGis.faild_rate = 0; + stGis.is_fault = stIec.bfault; + stGis.is_close = 1; // getGisOpenCloseState(stIec.site_id, stIec.eqm_code); + break; + default:; + } + } + } + // for test + //vGetHostTimeFmtBeforBay(sTime, 1); + //_SLEEP(1000); + //vGetHostTimeFmtBeforBay(eTime, 1); + // + switch (group) + { + case 1: // 主变高压侧电流电压组 + case 2: // 主变低压侧电流电压组 + snprintf(szSql, sizeof(szSql), "INSERT INTO iec_bydwork_param(id,site_id,eqm_code,system_code,stype,start_time,stop_time," + "higth_voltage,higth_current, record_date, ins_date) " + "VALUES(guuid(),'%s', '%s','%s', '%d', '%s', '%s', %.4f, %.4f, SYSDATE(), SYSDATE())", + stWork.site_id, stWork.eqm_code, stWork.system_code, stWork.state, sTime, eTime, stWork.voltage, stWork.current); + vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_bydwork_param: %s", szSql); + break; + case 3: // 主变运行工况组 + // 原始数据入库 + vTranHostTimeFmt(stRunState.chkTime, sTime); + memset(szSql, 0x00, sizeof(szSql)); + snprintf(szSql, sizeof(szSql), + "INSERT INTO transformer_run_status(id, main_tree_id, system_code, work_status, d_time, oil_temperature, oil_position," + "cooling_entry_pressure, cooling_exit_pressure, coolingwater_inlet_temperature,coolingwater_outlet_temperature," + "circulating_oil_inlet_pressure,circulating_oil_outlet_pressure,top_oil_temperature,oilpillow_oillevel," + "winding_temperature,circulating_oil_inlet_temperature,circulating_oil_out_temperature,site_id) " + // "VALUES(guuid(),'%s','%s','%d','%s', '%.4f', '%.4f', '%.4f', '%.4f','%.4f', '%.4f', '%.4f', '%.4f','%.4f', '%.4f', '%.4f','%s')", + "VALUES(guuid(),'%s','%s','%d','%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s','%s', '%s', '%s','%s','%s','%s')", + stRunState.eqm_code, stRunState.system_code, stRunState.wstate, sTime, + stRunState.dOilTemperature, + stRunState.dOilPosition, + stRunState.dcurJkyl, + stRunState.dcurCkyl, + stRunState.dCoolWaterTempEntry, + stRunState.dCoolWaterTempOuter, + stRunState.dOilPressEntry, + stRunState.dOilPressOuter, + stRunState.dOilTopTemp, + stRunState.dOilPillowLevel, + stRunState.dWindingTemp, + stRunState.dOilTempEntry, + stRunState.dOilTempOuter, + stRunState.site_id); + vPrtLogMsg(LOG_DEBUG, RET_OK, "transformer_run_status: %s", szSql); + break; + case 4: // 断路器电流电压组 + memset(szSql, 0x00, sizeof(szSql)); + vTranHostTimeFmt(stGis.d_time, sTime); + snprintf(szSql, sizeof(szSql), "INSERT INTO iec_breaker_param(id,site_id,eqm_code,system_code,d_time,work_state,abort_current,abort_voltage,faild_rate," + "is_fault,is_break,ins_date) " + "VALUES(guuid(),'%s', '%s', '%s','%s','%d',%.4f, %.4f, %.4f, '%d', '%d',SYSDATE())", + stGis.site_id, stGis.eqm_code, stGis.system_code, sTime, stGis.wstate, stGis.abort_current, stGis.abort_voltage, stGis.faild_rate, + stGis.is_fault, stGis.is_close); + vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_breaker_param: %s", szSql); + break; + default:; + } + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql); + } //vPrtLogMsg(LOG_WARNG, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql); +#endif // 0 } // 保存断路器断开数据记录 static void saveGisData(ST_BREAK_EQM_CODE &stGisRecord, unsigned char cState, time_t dtime) { - ST_IEC_GISBREAK_TABLE stGis; - ST_IECPOINT_TABLE stIec; - char szSql[DEF_BUFFER_1K] = { 0 }, szTime[32] = { 0 }; - - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) return; - - memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE)); - memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); - - stIec.sadr = stGisRecord.uiAbortCurrent; - if (true == bGetValueBySadr(stIec)) // 获取电流值 - stGis.abort_current = stIec.fval; - - memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); - stIec.sadr = stGisRecord.uiAbortVoltage; - if (true == bGetValueBySadr(stIec)) // 获取电压值 - stGis.abort_voltage = stIec.fval; - - strncpy((char *)stGis.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); - strncpy((char *)stGis.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); - strncpy((char *)stGis.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); - stGis.wstate = cGetCurrentWorkState(stIec.eqm_code); - stGis.faild_rate = 0; - stGis.is_fault = 0; - stGis.is_close = cState; - - vTranHostTimeFmt(dtime, szTime); - - snprintf(szSql, sizeof(szSql), "INSERT INTO iec_breaker_param(id,site_id,eqm_code,system_code,d_time,work_state,abort_current,abort_voltage,faild_rate," - "is_fault,is_break,ins_date) " - "VALUES(guuid(),'%s', '%s', '%s','%s','%d',%.4f, %.4f, %.4f, '%d', '%d',SYSDATE())", - stGis.site_id, stGis.eqm_code, stGis.system_code, szTime, stGis.wstate, stGis.abort_current, stGis.abort_voltage, stGis.faild_rate, - stGis.is_fault, stGis.is_close); - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql); - } +#if 0 + ST_IEC_GISBREAK_TABLE stGis; + ST_IECPOINT_TABLE stIec; + char szSql[DEF_BUFFER_1K] = { 0 }, szTime[32] = { 0 }; + + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) return; + + memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE)); + memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); + + stIec.sadr = stGisRecord.uiAbortCurrent; + if (true == bGetValueBySadr(stIec)) // 获取电流值 + stGis.abort_current = stIec.fval; + + memset(&stIec, 0x00, sizeof(ST_IECPOINT_TABLE)); + stIec.sadr = stGisRecord.uiAbortVoltage; + if (true == bGetValueBySadr(stIec)) // 获取电压值 + stGis.abort_voltage = stIec.fval; + + strncpy((char *)stGis.eqm_code, (char *)stIec.eqm_code, strlen((const char *)stIec.eqm_code)); + strncpy((char *)stGis.site_id, (char *)stIec.site_id, strlen((const char *)stIec.site_id)); + strncpy((char *)stGis.system_code, (char *)stIec.sys_code, strlen((const char *)stIec.sys_code)); + stGis.wstate = cGetCurrentWorkState(stIec.eqm_code); + stGis.faild_rate = 0; + stGis.is_fault = 0; + stGis.is_close = cState; + + vTranHostTimeFmt(dtime, szTime); + + snprintf(szSql, sizeof(szSql), "INSERT INTO iec_breaker_param(id,site_id,eqm_code,system_code,d_time,work_state,abort_current,abort_voltage,faild_rate," + "is_fault,is_break,ins_date) " + "VALUES(guuid(),'%s', '%s', '%s','%s','%d',%.4f, %.4f, %.4f, '%d', '%d',SYSDATE())", + stGis.site_id, stGis.eqm_code, stGis.system_code, szTime, stGis.wstate, stGis.abort_current, stGis.abort_voltage, stGis.faild_rate, + stGis.is_fault, stGis.is_close); + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql); + } +#endif // 0 } /*************************************************************************** @@ -2714,39 +2998,39 @@ static void saveGisData(ST_BREAK_EQM_CODE &stGisRecord, unsigned char cState, ti ***************************************************************************/ void * thread_gis_hold_proc(void * arg) { - ST_IECPOINT_TABLE pData; - ST_BREAK_EQM_CODE stGisRecord; - map::iterator m_pIter; - vPrtLogMsg(LOG_DEBUG, 0, "thread_gis_hold_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); - mutex_lock(g_list_pingce_mutex); - if (g_list_pingce.empty() || g_list_pingce.size() <= 0) { - mutex_unlock(g_list_pingce_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - memcpy(&pData, &(g_list_pingce.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 - g_list_pingce.pop_back(); // 由尾删除 - mutex_unlock(g_list_pingce_mutex); - - // 根据遥信的点位地址,获取该点对应的电流电压点位及其数据 - mutex_lock(g_map_gis_state_mutex); - memset(&stGisRecord, 0x00, sizeof(ST_BREAK_EQM_CODE)); - - m_pIter = g_map_gis_state.find(pData.sadr); - if (m_pIter == g_map_gis_state.end()) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "yx_asdr=%d can not config info, do not nothing", pData.sadr); - continue; - } - memcpy(&stGisRecord, &(m_pIter->second), sizeof(ST_BREAK_EQM_CODE)); - mutex_lock(g_map_gis_state_mutex); - - saveGisData(stGisRecord, pData.cval, pData.dtime); - } - return NULL; + ST_IECPOINT_TABLE pData; + ST_BREAK_EQM_CODE stGisRecord; + map::iterator m_pIter; + vPrtLogMsg(LOG_DEBUG, 0, "thread_gis_hold_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); + memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); + mutex_lock(g_list_pingce_mutex); + if (g_list_pingce.empty() || g_list_pingce.size() <= 0) { + mutex_unlock(g_list_pingce_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + memcpy(&pData, &(g_list_pingce.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 + g_list_pingce.pop_back(); // 由尾删除 + mutex_unlock(g_list_pingce_mutex); + + // 根据遥信的点位地址,获取该点对应的电流电压点位及其数据 + mutex_lock(g_map_gis_state_mutex); + memset(&stGisRecord, 0x00, sizeof(ST_BREAK_EQM_CODE)); + + m_pIter = g_map_gis_state.find(pData.sadr); + if (m_pIter == g_map_gis_state.end()) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "yx_asdr=%d can not config info, do not nothing", pData.sadr); + continue; + } + memcpy(&stGisRecord, &(m_pIter->second), sizeof(ST_BREAK_EQM_CODE)); + mutex_lock(g_map_gis_state_mutex); + + saveGisData(stGisRecord, pData.cval, pData.dtime); + } + return NULL; } /*************************************************************************** @@ -2759,61 +3043,61 @@ void * thread_gis_hold_proc(void * arg) #ifdef _DEF_DB_CHANGERATE void * thread_pingce_proc(void * arg) { - ST_IECPOINT_TABLE pData; - ST_SADR_MATCH adrList; - vPrtLogMsg(LOG_DEBUG, 0, "thread_pingce_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - #if 0 - memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); - mutex_lock(g_list_pingce_mutex); - if (g_list_pingce.empty() || g_list_pingce.size() <= 0) { - mutex_unlock(g_list_pingce_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - memcpy(&pData, &(g_list_pingce.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 - g_list_pingce.pop_back(); // 由尾删除 - mutex_unlock(g_list_pingce_mutex); - #endif + ST_IECPOINT_TABLE pData; + ST_SADR_MATCH adrList; + vPrtLogMsg(LOG_DEBUG, 0, "thread_pingce_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); +#if 0 + memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); + mutex_lock(g_list_pingce_mutex); + if (g_list_pingce.empty() || g_list_pingce.size() <= 0) { + mutex_unlock(g_list_pingce_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + memcpy(&pData, &(g_list_pingce.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 + g_list_pingce.pop_back(); // 由尾删除 + mutex_unlock(g_list_pingce_mutex); +#endif // 发生信号有变化且发生时间>0时,立即提取数据,加入数据入库队列中 - if (!g_IecCtrl.b_Signal && (time(NULL) - g_Internal_time < g_iec_conf.save_internal)) { // 超过设定保存时间间隔时 - _SLEEP(100); - continue; - } - if (!g_IecCtrl.isConnect) { - _SLEEP(100); - continue; - } - g_IecCtrl.b_Signal = false; - g_Internal_time = time(NULL); + if (!g_IecCtrl.b_Signal && (time(NULL) - g_Internal_time < g_iec_conf.save_internal)) { // 超过设定保存时间间隔时 + _SLEEP(100); + continue; + } + if (!g_IecCtrl.isConnect) { + _SLEEP(100); + continue; + } + g_IecCtrl.b_Signal = false; + g_Internal_time = time(NULL); memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); memset(&adrList, 0x00, sizeof(ST_SADR_MATCH)); - for (int i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + for (int i = 0; i < (int)g_iec_conf.iec_byq_count; i++) { - for(int group = 2; group <= 3; group++) + for (int group = 2; group <= 3; group++) { - switch(group) + switch (group) { - case 1: // - //pData.sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; //uiLowCurrent - //break; - case 2: - //pData.sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; //uiLowCurrent - - if (1 == cGetByqDeviceState(g_iec_conf.pstByqCode[i].szEqmCode)) // 获取工作状态 - pData.sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; //uiHighCurrent 发电时取高压侧电流电压 - else pData.sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; //uiLowCurrent 抽水/空闲时取低压侧电流电压 - break; - case 3: - pData.sadr = g_iec_conf.pstByqCode[i].uiWindingTemp; //uiLowCurrent - break; - default: { - pData.sadr = 0 ; - continue; - } + case 1: // + //pData.sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; //uiLowCurrent + //break; + case 2: + //pData.sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; //uiLowCurrent + + if (1 == cGetByqDeviceState(g_iec_conf.pstByqCode[i].szEqmCode)) // 获取工作状态 + pData.sadr = g_iec_conf.pstByqCode[i].uiHighCurrent; //uiHighCurrent 发电时取高压侧电流电压 + else pData.sadr = g_iec_conf.pstByqCode[i].uiLowCurrent; //uiLowCurrent 抽水/空闲时取低压侧电流电压 + break; + case 3: + pData.sadr = g_iec_conf.pstByqCode[i].uiWindingTemp; //uiLowCurrent + break; + default: { + pData.sadr = 0; + continue; + } } if (iGetSadrMatchRecord(pData.sadr, adrList) > 0) { @@ -2824,10 +3108,10 @@ void * thread_pingce_proc(void * arg) adrList.psadr = NULL; } } - pData.sadr = 0 ; + pData.sadr = 0; } } - for (int i = 0; i < (int)g_iec_conf.iec_break_count; i++) + for (int i = 0; i < (int)g_iec_conf.iec_break_count; i++) { pData.sadr = g_iec_conf.pstBrkCode[i].uiAbortCurrent; if (iGetSadrMatchRecord(pData.sadr, adrList) > 0) @@ -2842,7 +3126,7 @@ void * thread_pingce_proc(void * arg) pData.sadr = 0; } } - return NULL; + return NULL; } #else /*************************************************************************** @@ -2854,40 +3138,40 @@ void * thread_pingce_proc(void * arg) ***************************************************************************/ void * thread_pingce_proc(void * arg) { - ST_IECPOINT_TABLE pData; - ST_SADR_MATCH adrList; - time_t interTime = time(NULL); - _SLEEP(3000); - vPrtLogMsg(LOG_DEBUG, 0, "thread_pingce_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - - // 发生信号有变化且发生时间>0时,立即提取数据,加入数据入库队列中 - if (!g_IecCtrl.b_Signal && (time(NULL) - interTime < g_iec_conf.save_internal)) { // 超过设定保存时间间隔时 - _SLEEP(100); - continue; - } - if (!g_IecCtrl.isConnect) { - _SLEEP(100); - continue; - } - g_IecCtrl.b_Signal = false; - interTime = time(NULL); - for (int i = 1; i < 5; i++) - { - memset(&adrList, 0x00, sizeof(ST_SADR_MATCH)); - if (!bGetSadrMatchRecord(i, adrList)) continue; + ST_IECPOINT_TABLE pData; + ST_SADR_MATCH adrList; + time_t interTime = time(NULL); + _SLEEP(3000); + vPrtLogMsg(LOG_DEBUG, 0, "thread_pingce_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); + + // 发生信号有变化且发生时间>0时,立即提取数据,加入数据入库队列中 + if (!g_IecCtrl.b_Signal && (time(NULL) - interTime < g_iec_conf.save_internal)) { // 超过设定保存时间间隔时 + _SLEEP(100); + continue; + } + if (!g_IecCtrl.isConnect) { + _SLEEP(100); + continue; + } + g_IecCtrl.b_Signal = false; + interTime = time(NULL); + for (int i = 1; i < 5; i++) + { + memset(&adrList, 0x00, sizeof(ST_SADR_MATCH)); + if (!bGetSadrMatchRecord(i, adrList)) continue; vPrtLogMsg(LOG_WARNG, RET_FAIL, "get addr match relations, group=%d", i); - vBuildByqWorkParam(pData, adrList); - if (adrList.psadr) - { - free((void *)adrList.psadr); - adrList.psadr = NULL; - } - } - } - return NULL; + vBuildByqWorkParam(pData, adrList); + if (adrList.psadr) + { + free((void *)adrList.psadr); + adrList.psadr = NULL; + } + } + } + return NULL; } #endif /*************************************************************************** @@ -2898,178 +3182,181 @@ void * thread_pingce_proc(void * arg) ***************************************************************************/ void * thread_warn_proc(void * arg) { - int count = 0, n = 0; - double warn_val = 0.0f; // 告警值 - bool isWarn = false; - ST_IECPOINT_TABLE pData; - char szSql[1024] = { 0 }, szWaringTime[32] = { 0 }; - char szWarninfo[256] = { 0 }, szMsg[24] = { 0 }; // 告警信息 - vPrtLogMsg(LOG_DEBUG, 0, "thread_warn_proc = %d startup...", GETTID()); - while (g_Running) - { - pthread_testcancels(); - memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); - mutex_lock(g_list_warn_mutex); - count = g_list_warn.size(); - n = 0; - if (g_list_warn.empty() || g_list_warn.size() <= 0) { - mutex_unlock(g_list_warn_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 10); - continue; - } - - CDBMySQL *pdbHandle = CDBMySQL::Instance(); - if (!pdbHandle) { - mutex_unlock(g_list_warn_mutex); - _SLEEP(MAX_SLEEP_EMPTY * 5); - continue; - } - isWarn = false; - memcpy(&pData, &(g_list_warn.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 - g_list_warn.pop_back(); // 由尾删除 - mutex_unlock(g_list_warn_mutex); - - memset(szSql, 0x00, sizeof(szSql)); - - // 获取告警值 - warn_val = getThresholdValuse((const char*)pData.eqm_code, (const char*)pData.fieldname, pData.wstate); - if (warn_val <= 0) - { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "Noset asdr=%d warn_val=%.4f nval=%.4f eqm_code=%s wstate=%d warn_field=%s", - pData.sadr, warn_val, pData.fval, pData.eqm_code, pData.wstate, pData.fieldname); - continue; // 告警值为0时,无效 - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "findmatch warninfo, asdr=%d warn_val=%.4f nval=%.4f eqm_code=%s wstate=%d warn_field=%s", - pData.sadr, warn_val, pData.fval, pData.eqm_code, pData.wstate, pData.fieldname); - // 判断是否有告警 - if (pData.warnFlag == 1) // 大于预警值时报警 - { - if (pData.fval > warn_val && pData.fval != HT_INVALID_VALUE) { - isWarn = true; - vTranHostTimeFmt(pData.dtime, szWaringTime); - strcpy(szMsg, "超标"); - } - } - else if (pData.warnFlag == 2) // 小于预警值时报警 - { - if (pData.fval < warn_val && pData.fval != HT_INVALID_VALUE) { - isWarn = true; - vTranHostTimeFmt(pData.dtime, szWaringTime); - strcpy(szMsg, "未达标"); - } - } - if (isWarn) - { - char szUuid[64] = { 0 }; - getuuid(szUuid, sizeof(szUuid)); - // 插入告警表 - snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(id,eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,main_tree_id,run_state) " - "VALUES('%s','1', '9', '%s%s:%.4f', '%s', SYSDATE(), '1', '%s', '%s','%d')", - szUuid, pData.poidesc, szMsg, pData.fval, szWaringTime, pData.site_id, pData.eqm_code,pData.wstate); - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql); - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "INSERT INTO busi_eqm_warning message,SQL:%s", szSql); - - // 插入告警详细表 - char szSubUuid[64] = { 0 }; - getuuid(szSubUuid, sizeof(szSubUuid)); - memset(szSql, 0x00, sizeof(szSql)); - - snprintf(szWarninfo, sizeof(szWarninfo), - "{\"sadr\":\"%d\",\"thresholdValue\":\"%.4f\",\"currRealValue\":\"%.4f\",\"equipmentStatus\":\"%d\",\"collectDate\":\"%s\",\"ipaddr\":\"\",\"port\":\"\",\"msgInfo\":\"%s\",\"phase\":\"\"}", - pData.sadr, warn_val, pData.fval,pData.wstate, szWaringTime,pData.poidesc); - snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning_info(id,warning_id,warning_info) VALUES('%s','%s','%s')",szSubUuid, szUuid, szWarninfo); - if (!pdbHandle->InsertRecord((const char *)szSql)) { - vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning_info message failed,SQL:%s", szSql); - } - vPrtLogMsg(LOG_DEBUG, RET_OK, "INSERT INTO busi_eqm_warning_info message,SQL:%s", szSql); - } - } - return NULL; +#if 0 + int count = 0, n = 0; + double warn_val = 0.0f; // 告警值 + bool isWarn = false; + ST_IECPOINT_TABLE pData; + char szSql[1024] = { 0 }, szWaringTime[32] = { 0 }; + char szWarninfo[256] = { 0 }, szMsg[24] = { 0 }; // 告警信息 + vPrtLogMsg(LOG_DEBUG, 0, "thread_warn_proc = %d startup...", GETTID()); + while (g_Running) + { + pthread_testcancels(); + memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE)); + mutex_lock(g_list_warn_mutex); + count = g_list_warn.size(); + n = 0; + if (g_list_warn.empty() || g_list_warn.size() <= 0) { + mutex_unlock(g_list_warn_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 10); + continue; + } + + CDBMySQL *pdbHandle = CDBMySQL::Instance(); + if (!pdbHandle) { + mutex_unlock(g_list_warn_mutex); + _SLEEP(MAX_SLEEP_EMPTY * 5); + continue; + } + isWarn = false; + memcpy(&pData, &(g_list_warn.back()), sizeof(ST_IECPOINT_TABLE)); // 由尾取出 + g_list_warn.pop_back(); // 由尾删除 + mutex_unlock(g_list_warn_mutex); + + memset(szSql, 0x00, sizeof(szSql)); + + // 获取告警值 + warn_val = getThresholdValuse((const char*)pData.eqm_code, (const char*)pData.fieldname, pData.wstate); + if (warn_val <= 0) + { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "Noset asdr=%d warn_val=%.4f nval=%.4f eqm_code=%s wstate=%d warn_field=%s", + pData.sadr, warn_val, pData.fval, pData.eqm_code, pData.wstate, pData.fieldname); + continue; // 告警值为0时,无效 + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "findmatch warninfo, asdr=%d warn_val=%.4f nval=%.4f eqm_code=%s wstate=%d warn_field=%s", + pData.sadr, warn_val, pData.fval, pData.eqm_code, pData.wstate, pData.fieldname); + // 判断是否有告警 + if (pData.warnFlag == 1) // 大于预警值时报警 + { + if (pData.fval > warn_val && pData.fval != HT_INVALID_VALUE) { + isWarn = true; + vTranHostTimeFmt(pData.dtime, szWaringTime); + strcpy(szMsg, "超标"); + } + } + else if (pData.warnFlag == 2) // 小于预警值时报警 + { + if (pData.fval < warn_val && pData.fval != HT_INVALID_VALUE) { + isWarn = true; + vTranHostTimeFmt(pData.dtime, szWaringTime); + strcpy(szMsg, "未达标"); + } + } + if (isWarn) + { + char szUuid[64] = { 0 }; + getuuid(szUuid, sizeof(szUuid)); + // 插入告警表 + snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(id,eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,main_tree_id,run_state) " + "VALUES('%s','1', '9', '%s%s:%.4f', '%s', SYSDATE(), '1', '%s', '%s','%d')", + szUuid, pData.poidesc, szMsg, pData.fval, szWaringTime, pData.site_id, pData.eqm_code, pData.wstate); + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql); + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "INSERT INTO busi_eqm_warning message,SQL:%s", szSql); + + // 插入告警详细表 + char szSubUuid[64] = { 0 }; + getuuid(szSubUuid, sizeof(szSubUuid)); + memset(szSql, 0x00, sizeof(szSql)); + + snprintf(szWarninfo, sizeof(szWarninfo), + "{\"sadr\":\"%d\",\"thresholdValue\":\"%.4f\",\"currRealValue\":\"%.4f\",\"equipmentStatus\":\"%d\",\"collectDate\":\"%s\",\"ipaddr\":\"\",\"port\":\"\",\"msgInfo\":\"%s\",\"phase\":\"\"}", + pData.sadr, warn_val, pData.fval, pData.wstate, szWaringTime, pData.poidesc); + snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning_info(id,warning_id,warning_info) VALUES('%s','%s','%s')", szSubUuid, szUuid, szWarninfo); + if (!pdbHandle->InsertRecord((const char *)szSql)) { + vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning_info message failed,SQL:%s", szSql); + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "INSERT INTO busi_eqm_warning_info message,SQL:%s", szSql); + } + } +#endif + + return NULL; } // 负荷数据数据入库 void dbSet_iec_bydwork_param(ST_IEC_BYQWORK_TABLE *pstWork) { - /* - bool isChange = false; // 数据是否和最近一次的发生变化了 - map::iterator m_pIter; - if (!pstWork->eqm_code && strlen((char*)pstWork->eqm_code) <= 0) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "dbSet_iec_bydwork_param: eqm_code is null,please check config file or coding."); - return; - } - - mutex_lock(g_map_byq_mutex); - m_pIter = g_map_byq.find((char*)pstWork->eqm_code); - if (m_pIter != g_map_byq.end()) - { - if (pstWork->current > 0 && pstWork->current != (m_pIter->second).stLastData.current) - { - isChange = true; // 数据是否和最近一次的发生变化了 - (m_pIter->second).stLastData.current = pstWork->current; //覆盖最近一次的数据 - } - else pstWork->current = (m_pIter->second).stLastData.current; // 沿用最近一次的数据 - - if (pstWork->voltage > 0 && pstWork->voltage != (m_pIter->second).stLastData.voltage) - { - isChange = true; // 数据是否和最近一次的发生变化了 - (m_pIter->second).stLastData.voltage = pstWork->voltage; - } - else pstWork->voltage = (m_pIter->second).stLastData.voltage; - - if ((pstWork->stype & 0xff) > 0x00) { - if ((pstWork->stype & 0xff) == (m_pIter->second).stLastData.stype) - pstWork->start_time = (m_pIter->second).stLastData.start_time; // 状态未发生变化,则开始时间沿用之前的时间 - else { - (m_pIter->second).stLastData.stype = (pstWork->stype & 0xff); // 状态发生了变化 - pstWork->start_time = time(NULL); - (m_pIter->second).stLastData.start_time = time(NULL); - isChange = true; - } - } - else { - pstWork->stype = (m_pIter->second).stLastData.stype; // 状态=0时,无效值,沿用上一次的状态。 - pstWork->start_time = (m_pIter->second).stLastData.start_time; - } + /* + bool isChange = false; // 数据是否和最近一次的发生变化了 + map::iterator m_pIter; + if (!pstWork->eqm_code && strlen((char*)pstWork->eqm_code) <= 0) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "dbSet_iec_bydwork_param: eqm_code is null,please check config file or coding."); + return; + } + + mutex_lock(g_map_byq_mutex); + m_pIter = g_map_byq.find((char*)pstWork->eqm_code); + if (m_pIter != g_map_byq.end()) + { + if (pstWork->current > 0 && pstWork->current != (m_pIter->second).stLastData.current) + { + isChange = true; // 数据是否和最近一次的发生变化了 + (m_pIter->second).stLastData.current = pstWork->current; //覆盖最近一次的数据 + } + else pstWork->current = (m_pIter->second).stLastData.current; // 沿用最近一次的数据 + + if (pstWork->voltage > 0 && pstWork->voltage != (m_pIter->second).stLastData.voltage) + { + isChange = true; // 数据是否和最近一次的发生变化了 + (m_pIter->second).stLastData.voltage = pstWork->voltage; + } + else pstWork->voltage = (m_pIter->second).stLastData.voltage; + + if ((pstWork->stype & 0xff) > 0x00) { + if ((pstWork->stype & 0xff) == (m_pIter->second).stLastData.stype) + pstWork->start_time = (m_pIter->second).stLastData.start_time; // 状态未发生变化,则开始时间沿用之前的时间 + else { + (m_pIter->second).stLastData.stype = (pstWork->stype & 0xff); // 状态发生了变化 + pstWork->start_time = time(NULL); + (m_pIter->second).stLastData.start_time = time(NULL); + isChange = true; + } + } + else { + pstWork->stype = (m_pIter->second).stLastData.stype; // 状态=0时,无效值,沿用上一次的状态。 + pstWork->start_time = (m_pIter->second).stLastData.start_time; + } #ifdef _SITE_ID_TYPE_INT - if (pstWork->site_id <= 0) pstWork->site_id = (m_pIter->second).SiteID; + if (pstWork->site_id <= 0) pstWork->site_id = (m_pIter->second).SiteID; #else - if (strlen((const char*)pstWork->site_id) <= 0) - strcpy((char*)pstWork->site_id , (const char*)((m_pIter->second).SiteID)); + if (strlen((const char*)pstWork->site_id) <= 0) + strcpy((char*)pstWork->site_id , (const char*)((m_pIter->second).SiteID)); #endif - pstWork->stop_time = time(NULL); - */ - // if (isChange) // 数据未有变化,无需入库操作 -// if ((pstWork->state & 0xff) != 0x03) -// { -// // 数据入库 -// char szSql[DEF_BUFFER_1K] = { 0 }; -// char sTime[21] = { 0 }, eTime[21] = { 0 }; -// CDBMySQL *pdbHandle = CDBMySQL::Instance(); -// if (!pdbHandle) return; -// -// vTranHostTimeFmt(pstWork->start_time, sTime); -// vTranHostTimeFmt(pstWork->stop_time, eTime); -//#ifdef _SITE_ID_TYPE_INT -// sprintf(szSql, "INSERT INTO iec_bydwork_param(site_id,eqm_code,stype,start_time,stop_time," -// "higth_voltage,higth_current, record_date, ins_date) " -// "VALUES(%d, '%s', %d, '%s', '%s', %.2f, %.2f, SYSDATE(), SYSDATE())", -// pstWork->site_id, pstWork->eqm_code, pstWork->state, sTime, eTime, pstWork->voltage, pstWork->current); -//#else -// snprintf(szSql, sizeof(szSql), "INSERT INTO iec_bydwork_param(site_id,eqm_code,stype,start_time,stop_time," -// "higth_voltage,higth_current, record_date, ins_date) " -// "VALUES('%s', '%s', %d, '%s', '%s', %.2f, %.2f, SYSDATE(), SYSDATE())", -// pstWork->site_id, pstWork->eqm_code, pstWork->state, sTime, eTime, pstWork->voltage, pstWork->current); -//#endif -// vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_bydwork_param: %s", szSql); -// if (!pdbHandle->InsertRecord((const char *)szSql)) { -// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO iec_bydwork_param message failed,SQL:%s", szSql); -// } -// } - //} - //mutex_unlock(g_map_byq_mutex); - return; + pstWork->stop_time = time(NULL); + */ + // if (isChange) // 数据未有变化,无需入库操作 + // if ((pstWork->state & 0xff) != 0x03) + // { + // // 数据入库 + // char szSql[DEF_BUFFER_1K] = { 0 }; + // char sTime[21] = { 0 }, eTime[21] = { 0 }; + // CDBMySQL *pdbHandle = CDBMySQL::Instance(); + // if (!pdbHandle) return; + // + // vTranHostTimeFmt(pstWork->start_time, sTime); + // vTranHostTimeFmt(pstWork->stop_time, eTime); + //#ifdef _SITE_ID_TYPE_INT + // sprintf(szSql, "INSERT INTO iec_bydwork_param(site_id,eqm_code,stype,start_time,stop_time," + // "higth_voltage,higth_current, record_date, ins_date) " + // "VALUES(%d, '%s', %d, '%s', '%s', %.2f, %.2f, SYSDATE(), SYSDATE())", + // pstWork->site_id, pstWork->eqm_code, pstWork->state, sTime, eTime, pstWork->voltage, pstWork->current); + //#else + // snprintf(szSql, sizeof(szSql), "INSERT INTO iec_bydwork_param(site_id,eqm_code,stype,start_time,stop_time," + // "higth_voltage,higth_current, record_date, ins_date) " + // "VALUES('%s', '%s', %d, '%s', '%s', %.2f, %.2f, SYSDATE(), SYSDATE())", + // pstWork->site_id, pstWork->eqm_code, pstWork->state, sTime, eTime, pstWork->voltage, pstWork->current); + //#endif + // vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_bydwork_param: %s", szSql); + // if (!pdbHandle->InsertRecord((const char *)szSql)) { + // vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO iec_bydwork_param message failed,SQL:%s", szSql); + // } + // } + //} + //mutex_unlock(g_map_byq_mutex); + return; } // 运行工况数据入库 //void dbSet_transformer_read_table(ST_IEC_BYQREAD_TABLE *pstRung) @@ -3271,86 +3558,88 @@ void dbSet_iec_bydwork_param(ST_IEC_BYQWORK_TABLE *pstWork) // 刷新设备运行状态:1:发电、2:抽水、3:空闲 unsigned char getDevWorkState(ST_IECPOINT_TABLE &stIec) { - bool b_byq_close = false, b_byq_fd = false, b_byq_cs = false; - unsigned char cstate = 0; - int s = 0; //对于一个主变设备的状态检索,最多找到3个遥信量即可,不必检索所有的map列表 - unsigned char szMEqmCode[DEF_EQM_CODE_SIZE] = { 0 }; // 主变ID - - // 先根据设备类型区分出是主变设备/GIS设备 - if ((stIec.eqm_type & 0xff) != 1) // GIS设备 - { - //根据隶属关系表,获取主设备id - if (!bGetMasterEqmCodeBySubEqmCode(stIec.site_id, stIec.eqm_code, szMEqmCode)) { - vPrtLogMsg(LOG_WARNG, RET_FAIL, "from s_eqm_code:%s find m_eqm_code, not found,please check device build relations...", stIec.eqm_code); - return 0x03; // 默认置为空闲状态 - } - } - else { - strcpy((char*)szMEqmCode, (const char*)stIec.eqm_code); // 主变ID - } - - //根据主变设备ID,找出其遥信地址,然后依据遥信量(3个)确定设备的工作状态 - map::iterator m_pIter; - for (m_pIter = g_map_iec.begin(); ((m_pIter != g_map_iec.end()) && (s < 3)); m_pIter++) - { - if (((m_pIter->second).stype & 0xff) != 1) continue; // 确定遥信量 - if (((m_pIter->second).eqm_type & 0xff) != 1) continue; // 变压器设备 - if (0 != stringncasecmp((const char*)((m_pIter->second).site_id), (const char*)stIec.site_id, strlen((const char*)stIec.site_id))) continue; - if (0 != stringncasecmp((const char*)((m_pIter->second).eqm_code), (const char*)szMEqmCode, strlen((const char*)szMEqmCode))) continue; - switch ((m_pIter->second).isget) - { - case 1: // 1号发电机出口开关合位 - if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_close = true; - s++; - break; - case 2: // 1号机组发电换相刀闸合位 - if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_fd = true; - s++; - break; - case 3: // 1号机组抽水换相刀闸合位 - if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_cs = true; - s++; - break; - default:; - } - } - // 判断开关量 - if (b_byq_close) - { - if (b_byq_fd) cstate = 0x01; // 发电状态 - else if (b_byq_cs) cstate = 0x02; // 抽水状态 - else cstate = 0x03; // 空闲状态 - } - else cstate = 0x03; // 空闲状态 - flushDevWorkState(stIec.site_id, szMEqmCode, cstate); - vSetByqDeviceState(szMEqmCode, cstate); - return cstate; + bool b_byq_close = false, b_byq_fd = false, b_byq_cs = false; + unsigned char cstate = 0; + int s = 0; //对于一个主变设备的状态检索,最多找到3个遥信量即可,不必检索所有的map列表 + unsigned char szMEqmCode[DEF_EQM_CODE_SIZE] = { 0 }; // 主变ID + + // 先根据设备类型区分出是主变设备/GIS设备 + if ((stIec.eqm_type & 0xff) != 1) // GIS设备 + { + //根据隶属关系表,获取主设备id + if (!bGetMasterEqmCodeBySubEqmCode(stIec.site_id, stIec.eqm_code, szMEqmCode)) { + vPrtLogMsg(LOG_WARNG, RET_FAIL, "from s_eqm_code:%s find m_eqm_code, not found,please check device build relations...", stIec.eqm_code); + return 0x03; // 默认置为空闲状态 + } + } + else { + strcpy((char*)szMEqmCode, (const char*)stIec.eqm_code); // 主变ID + } + + //根据主变设备ID,找出其遥信地址,然后依据遥信量(3个)确定设备的工作状态 + map::iterator m_pIter; + for (m_pIter = g_map_iec.begin(); ((m_pIter != g_map_iec.end()) && (s < 3)); m_pIter++) + { + if (((m_pIter->second).stype & 0xff) != 1) continue; // 确定遥信量 + if (((m_pIter->second).eqm_type & 0xff) != 1) continue; // 变压器设备 + if (0 != stringncasecmp((const char*)((m_pIter->second).site_id), (const char*)stIec.site_id, strlen((const char*)stIec.site_id))) continue; + if (0 != stringncasecmp((const char*)((m_pIter->second).eqm_code), (const char*)szMEqmCode, strlen((const char*)szMEqmCode))) continue; + switch ((m_pIter->second).isget) + { + case 1: // 1号发电机出口开关合位 + if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_close = true; + s++; + break; + case 2: // 1号机组发电换相刀闸合位 + if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_fd = true; + s++; + break; + case 3: // 1号机组抽水换相刀闸合位 + if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_cs = true; + s++; + break; + default:; + } + } + // 判断开关量 + if (b_byq_close) + { + if (b_byq_fd) cstate = 0x01; // 发电状态 + else if (b_byq_cs) cstate = 0x02; // 抽水状态 + else cstate = 0x03; // 空闲状态 + } + else cstate = 0x03; // 空闲状态 + flushDevWorkState(stIec.site_id, szMEqmCode, cstate); + vSetByqDeviceState(szMEqmCode, cstate); + return cstate; } // 主变设备运行事故状态: 4:机组电气事故 unsigned char getDevFaultState(ST_IECPOINT_TABLE &stIec) { - unsigned char isFault = 0; - map::iterator m_pIter; - - if (stIec.eqm_type != 1) return 0; // 只有主变有事故状态. - for (m_pIter = g_map_iec.begin(); m_pIter != g_map_iec.end(); m_pIter++) - { - if ((m_pIter->second).stype != 1) continue; // 不是遥信量 - if (0 != stringncasecmp((const char*)(m_pIter->second).site_id, (const char*)stIec.site_id, strlen((const char*)stIec.site_id))) continue; - if (0 != stringncasecmp((const char*)(m_pIter->second).eqm_code, (const char*)stIec.eqm_code, strlen((const char*)stIec.eqm_code))) continue; - switch ((m_pIter->second).isget) - { - case 4: // 1号机组电气事故,1:事故 0:正常 - if (((m_pIter->second).cval & 0xff) == 0x01) { - isFault = 1; - } - default:; - } - } - flushFaultState(stIec.site_id, stIec.eqm_code, isFault); - vSetByqDeviceFaultState(stIec.eqm_code, isFault); - return isFault; + unsigned char isFault = 0; +#if 0 + map::iterator m_pIter; + + if (stIec.eqm_type != 1) return 0; // 只有主变有事故状态. + for (m_pIter = g_map_iec.begin(); m_pIter != g_map_iec.end(); m_pIter++) + { + if ((m_pIter->second).stype != 1) continue; // 不是遥信量 + if (0 != stringncasecmp((const char*)(m_pIter->second).site_id, (const char*)stIec.site_id, strlen((const char*)stIec.site_id))) continue; + if (0 != stringncasecmp((const char*)(m_pIter->second).eqm_code, (const char*)stIec.eqm_code, strlen((const char*)stIec.eqm_code))) continue; + switch ((m_pIter->second).isget) + { + case 4: // 1号机组电气事故,1:事故 0:正常 + if (((m_pIter->second).cval & 0xff) == 0x01) { + isFault = 1; + } + default:; + } + } + flushFaultState(stIec.site_id, stIec.eqm_code, isFault); + vSetByqDeviceFaultState(stIec.eqm_code, isFault); +#endif // 0 + return isFault; } @@ -3580,46 +3869,46 @@ unsigned char getDevFaultState(ST_IECPOINT_TABLE &stIec) //void *thread_setdb_proc(void *arg) //{ // vPrtLogMsg(LOG_DEBUG, 0, "thread_setdb_proc = %d startup...", GETTID()); - //ST_DB_DATA stdbSet; - - //while (g_Running) - //{ - // pthread_testcancels(); - // memset(&stdbSet, 0x00, sizeof(ST_DB_DATA)); - // mutex_lock(g_list_dbset_mutex); - // if (g_list_dbset.empty() || g_list_dbset.size() <= 0) { - // mutex_unlock(g_list_dbset_mutex); - // _SLEEP(MAX_SLEEP_EMPTY * 10); - // continue; - // } - // memcpy(&stdbSet, &(g_list_dbset.back()), sizeof(ST_DB_DATA)); // 由尾取出 - // if (stdbSet.pData == NULL) { - // mutex_unlock(g_list_dbset_mutex); - // _SLEEP(MAX_SLEEP_EMPTY * 10); - // continue; - // } - // g_list_dbset.pop_back(); // 由尾删除 - // mutex_unlock(g_list_dbset_mutex); - - // // 根据不同的数据类型分别入库 - // switch (stdbSet.ctype) - // { - // case 1: // 1:运行工况数据入库 transformer_read_table - // dbSet_transformer_read_table((ST_IEC_BYQREAD_TABLE*)stdbSet.pData); - // //dbSet_transformer_read_table_cache((ST_IEC_BYQREAD_TABLE*)stdbSet.pData); - // break; - // case 2: // 2:GIS负荷数据入库 iec_breaker_param - // dbSet_iec_breaker_param((ST_IEC_GISBREAK_TABLE*)stdbSet.pData); - // break; - // case 3: // 3:负荷数据入库 iec_bydwork_param - // dbSet_iec_bydwork_param((ST_IEC_BYQWORK_TABLE*)stdbSet.pData); - // break; - // default: - // break; - // } // end switch - // free(stdbSet.pData); - // stdbSet.pData = NULL; - //} + //ST_DB_DATA stdbSet; + + //while (g_Running) + //{ + // pthread_testcancels(); + // memset(&stdbSet, 0x00, sizeof(ST_DB_DATA)); + // mutex_lock(g_list_dbset_mutex); + // if (g_list_dbset.empty() || g_list_dbset.size() <= 0) { + // mutex_unlock(g_list_dbset_mutex); + // _SLEEP(MAX_SLEEP_EMPTY * 10); + // continue; + // } + // memcpy(&stdbSet, &(g_list_dbset.back()), sizeof(ST_DB_DATA)); // 由尾取出 + // if (stdbSet.pData == NULL) { + // mutex_unlock(g_list_dbset_mutex); + // _SLEEP(MAX_SLEEP_EMPTY * 10); + // continue; + // } + // g_list_dbset.pop_back(); // 由尾删除 + // mutex_unlock(g_list_dbset_mutex); + + // // 根据不同的数据类型分别入库 + // switch (stdbSet.ctype) + // { + // case 1: // 1:运行工况数据入库 transformer_read_table + // dbSet_transformer_read_table((ST_IEC_BYQREAD_TABLE*)stdbSet.pData); + // //dbSet_transformer_read_table_cache((ST_IEC_BYQREAD_TABLE*)stdbSet.pData); + // break; + // case 2: // 2:GIS负荷数据入库 iec_breaker_param + // dbSet_iec_breaker_param((ST_IEC_GISBREAK_TABLE*)stdbSet.pData); + // break; + // case 3: // 3:负荷数据入库 iec_bydwork_param + // dbSet_iec_bydwork_param((ST_IEC_BYQWORK_TABLE*)stdbSet.pData); + // break; + // default: + // break; + // } // end switch + // free(stdbSet.pData); + // stdbSet.pData = NULL; + //} // return NULL; //} /*************************************************************************** @@ -3773,89 +4062,89 @@ unsigned char getDevFaultState(ST_IECPOINT_TABLE &stIec) ***************************************************************************/ void *thread_Timer_proc(void *arg) { - vPrtLogMsg(LOG_DEBUG, 0, "thread_Timer_proc = %d startup...", GETTID()); - while (g_Running) - { - if (!g_IecCtrl.isConnect) - { - _SLEEP(1000); - continue; - } - // 间隔1s - time_t timeOrigin = time(NULL); - - // 定期总召 - /* - if ((g_IecCtrl.time_action != -1) && ((timeOrigin - g_IecCtrl.time_action) > g_iec_conf.action_interval)) - { - vPrtLogMsg(LOG_DEBUG, RET_OK, "Send Activation"); - SendMsgFormatIAction(CMD_CTL_64H); // 发送总召激活 - } - * */ - - _SLEEP(1000); - // continue; - - while ((time(NULL) - timeOrigin) < 1000) _SLEEP(1000); - - if (!g_IecCtrl.isConnect) // t0时间内连接未建立则重新连接并发送U启动帧激活数据传输 - { - // time-out for reconnection. - g_IecCtrl.timer_t0++; // t0++ - if (g_IecCtrl.timer_t0 > g_IecCtrl.t0) // TCP连接建立的超时时间(超时重新连接) - { - g_IecCtrl.timer_t0 = 0; - g_IecCtrl.isConnect = false; - //if (master->OpenLink(master->RemoteHost, master->RemotePort) == EOK) - //SendMsgFormatU(CMD_STARTDT); - } - } - else - { - // maximun number of frames received before master send ACK. W - if ((g_IecCtrl.RxCounter - g_IecCtrl.LastAckRx) >= g_IecCtrl.w * 2) - // Send_S_Msg(); - // time-out of waiting ACK to Sended APDU o TestFR - g_IecCtrl.timer_Confirm++; - // t1:RTU(服务器)端启动U格式测试过程后等待U格式测试应答的超时时间(超时处理:断开连接) - if (g_IecCtrl.timer_Confirm > g_IecCtrl.timer_t1) - { - if (g_IecCtrl.TxCounter - g_IecCtrl.LastAckTx > 6) - { + vPrtLogMsg(LOG_DEBUG, 0, "thread_Timer_proc = %d startup...", GETTID()); + while (g_Running) + { + if (!g_IecCtrl.isConnect) + { + _SLEEP(1000); + continue; + } + // 间隔1s + time_t timeOrigin = time(NULL); + + // 定期总召 + /* + if ((g_IecCtrl.time_action != -1) && ((timeOrigin - g_IecCtrl.time_action) > g_iec_conf.action_interval)) + { + vPrtLogMsg(LOG_DEBUG, RET_OK, "Send Activation"); + SendMsgFormatIAction(CMD_CTL_64H); // 发送总召激活 + } + * */ + + _SLEEP(1000); + // continue; + + while ((time(NULL) - timeOrigin) < 1000) _SLEEP(1000); + + if (!g_IecCtrl.isConnect) // t0时间内连接未建立则重新连接并发送U启动帧激活数据传输 + { + // time-out for reconnection. + g_IecCtrl.timer_t0++; // t0++ + if (g_IecCtrl.timer_t0 > g_IecCtrl.t0) // TCP连接建立的超时时间(超时重新连接) + { + g_IecCtrl.timer_t0 = 0; + g_IecCtrl.isConnect = false; + //if (master->OpenLink(master->RemoteHost, master->RemotePort) == EOK) + //SendMsgFormatU(CMD_STARTDT); + } + } + else + { + // maximun number of frames received before master send ACK. W + if ((g_IecCtrl.RxCounter - g_IecCtrl.LastAckRx) >= g_IecCtrl.w * 2) + // Send_S_Msg(); + // time-out of waiting ACK to Sended APDU o TestFR + g_IecCtrl.timer_Confirm++; + // t1:RTU(服务器)端启动U格式测试过程后等待U格式测试应答的超时时间(超时处理:断开连接) + if (g_IecCtrl.timer_Confirm > g_IecCtrl.timer_t1) + { + if (g_IecCtrl.TxCounter - g_IecCtrl.LastAckTx > 6) + { vPrtLogMsg(LOG_WARNG, 0, "Wait for U RESP timeout: TxCounter=%d LastAckTx=%d > 6, will close socket", g_IecCtrl.TxCounter, g_IecCtrl.LastAckTx); - g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); - g_IecCtrl.isConnect = false; - - - } - // g_IecCtrl.timer_Confirmflag = true; - } - - // time-out for no data to send, send S-frame to ack data received. OK - g_IecCtrl.timer_t2++; - // t2规定接收方在接收到I格式报文后,若经过t2时间未再收到新的I格式报文, - // 则必须向发送方发送S格式帧对已经接收到的I格式报文进行认可,显然t2必须小于t1。 - if (g_IecCtrl.timer_t2 > g_IecCtrl.t2) // (T2 < T1). S格式的超时时间 - { - g_IecCtrl.timer_t2 = 0; - if (g_IecCtrl.timer_S_Ackflag) // 在收到I格式报文的时候置timer_S_Ack为0 - SendMsgFormatS(g_IecCtrl.usSendNo); - g_IecCtrl.timer_S_Ackflag = true; - } - - // time-out for idle status, send test frame to check link state. OK - // t3规定调度端或子站RTU端每接收一帧 I帧、S帧或者U帧将重新触发计时器t3,若在t3内未接收到任何报文,将向对方发送测试链路帧 - g_IecCtrl.timer_t3++; - if (g_IecCtrl.timer_t3 > g_IecCtrl.t3) // 没有实际的数据交换时,任何一端启动U格式测试过程的最大间隔时间 (发送测试帧) - { - g_IecCtrl.timer_t3 = 0; - if (g_IecCtrl.timer_U_Testflag) // 接收到I S U帧都将timer_U_Test置为0 - SendMsgFormatU(CMD_TESTFR); - g_IecCtrl.timer_U_Testflag = true; - } - } - } - return NULL; + g_Tcp.tcpCloseSocket(g_IecCtrl.sockid); + g_IecCtrl.isConnect = false; + + + } + // g_IecCtrl.timer_Confirmflag = true; + } + + // time-out for no data to send, send S-frame to ack data received. OK + g_IecCtrl.timer_t2++; + // t2规定接收方在接收到I格式报文后,若经过t2时间未再收到新的I格式报文, + // 则必须向发送方发送S格式帧对已经接收到的I格式报文进行认可,显然t2必须小于t1。 + if (g_IecCtrl.timer_t2 > g_IecCtrl.t2) // (T2 < T1). S格式的超时时间 + { + g_IecCtrl.timer_t2 = 0; + if (g_IecCtrl.timer_S_Ackflag) // 在收到I格式报文的时候置timer_S_Ack为0 + SendMsgFormatS(&g_IecCtrl, g_IecCtrl.usSendNo); + g_IecCtrl.timer_S_Ackflag = true; + } + + // time-out for idle status, send test frame to check link state. OK + // t3规定调度端或子站RTU端每接收一帧 I帧、S帧或者U帧将重新触发计时器t3,若在t3内未接收到任何报文,将向对方发送测试链路帧 + g_IecCtrl.timer_t3++; + if (g_IecCtrl.timer_t3 > g_IecCtrl.t3) // 没有实际的数据交换时,任何一端启动U格式测试过程的最大间隔时间 (发送测试帧) + { + g_IecCtrl.timer_t3 = 0; + if (g_IecCtrl.timer_U_Testflag) // 接收到I S U帧都将timer_U_Test置为0 + SendMsgFormatU(&g_IecCtrl, CMD_TESTFR); + g_IecCtrl.timer_U_Testflag = true; + } + } + } + return NULL; } /*************************************************************************** @@ -3866,34 +4155,40 @@ void *thread_Timer_proc(void *arg) ***************************************************************************/ void *thread_active_proc(void *arg) { - vPrtLogMsg(LOG_DEBUG, 0, "thread_active_proc = %d startup...", GETTID()); - ST_APCI header; - while (g_Running && g_IecCtrl.isConnect) - { - if (time(NULL) - g_IecCtrl.last_time > g_TConfig.getTimeout3()) { - header.start = 0x68; - header.len = 0x04; - vAutoSendSeqNo(1); // 发送序列号增1 - header.cntl1 = g_IecCtrl.usSendNo & 0xFF; // S-Format - header.cntl2 = (g_IecCtrl.usSendNo >> 8) & 0xFF; - header.cntl3 = g_IecCtrl.usRecvNo & 0xFE; - header.cntl4 = (g_IecCtrl.usRecvNo >> 8) & 0xFF; + ST_IEC104_CTRL* pIecCtrl = (ST_IEC104_CTRL *)arg; + + time_t ts = 0; + vPrtLogMsg(LOG_DEBUG, 0, "thread_active_proc = %d startup...", GETTID()); + ST_APCI header; + while (g_Running && pIecCtrl->isConnect) + { + ts = time(NULL); + + if (ts - pIecCtrl->last_time > g_TConfig.getTimeout3()) { + header.start = 0x68; + header.len = 0x04; + vAutoSendSeqNo(pIecCtrl, 1); // 发送序列号增1 + header.cntl1 = pIecCtrl->usSendNo & 0xFF; // S-Format + header.cntl2 = (pIecCtrl->usSendNo >> 8) & 0xFF; + header.cntl3 = pIecCtrl->usRecvNo & 0xFE; + header.cntl4 = (pIecCtrl->usRecvNo >> 8) & 0xFF; #ifndef _WIN32 - g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, 6, g_IecCtrl.pipeFds[0]); + g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&header, 6, g_IecCtrl.pipeFds[0]); #else - g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, 6, -1); + g_Tcp.tcpSendBuffer(pIecCtrl->sockid, (const char*)&header, 6, -1); #endif - vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); - mutex_lock(g_IecCtrl_mutex); - g_IecCtrl.last_time = time(NULL); - mutex_unlock(g_IecCtrl_mutex); - } - //vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)CMD_ACTIVE_PACKAGE, sizeof(ST_APCI)); + vPrtLogHex(LOG_PACK, pIecCtrl->sockid, PRT_PACK_SEND, (unsigned char*)&header, sizeof(ST_APCI)); + // mutex_lock(g_IecCtrl_mutex); + pIecCtrl->last_time = time(NULL); + // mutex_unlock(g_IecCtrl_mutex); + } + + //vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)CMD_ACTIVE_PACKAGE, sizeof(ST_APCI)); //vPrtListCount(); - _SLEEP(1000); - } - return NULL; + _SLEEP(1000); + } + return NULL; } // 获取最近一次变压器的数据 @@ -4042,28 +4337,28 @@ void *thread_active_proc(void *arg) // 设置主变的油位信息体地址 bool bSetBYQPointValueByAddr(const char *pszEqmCode, float value) { - unsigned int sdr = 0; - for (int i = 0; i < (int)g_iec_conf.iec_byq_count; i++) - { - if (0 == stringncasecmp(pszEqmCode, (const char*)(g_iec_conf.pstByqCode[i].szEqmCode), strlen(pszEqmCode))) - { - g_IecCtrl.m_gis_change = true; // 通知,需保存一条记录 - switch (i) - { - case 0: - return bSetPointTableValueYC(value, (unsigned int)16405); - case 1: - return bSetPointTableValueYC(value, (unsigned int)16426); - case 2: - return bSetPointTableValueYC(value, (unsigned int)16447); - case 3: - return bSetPointTableValueYC(value, (unsigned int)16468); - default: - break; - } - } - } - return false; + unsigned int sdr = 0; + for (int i = 0; i < (int)g_iec_conf.iec_byq_count; i++) + { + if (0 == stringncasecmp(pszEqmCode, (const char*)(g_iec_conf.pstByqCode[i].szEqmCode), strlen(pszEqmCode))) + { + g_IecCtrl.m_gis_change = true; // 通知,需保存一条记录 + switch (i) + { + case 0: + return bSetPointTableValueYC(value, (unsigned int)16405); + case 1: + return bSetPointTableValueYC(value, (unsigned int)16426); + case 2: + return bSetPointTableValueYC(value, (unsigned int)16447); + case 3: + return bSetPointTableValueYC(value, (unsigned int)16468); + default: + break; + } + } + } + return false; } @@ -4274,31 +4569,31 @@ bool bSetBYQPointValueByAddr(const char *pszEqmCode, float value) // 统计发电、抽水时间 void vIECWorkTime() { - char szSql[1024] = { 0 }; - - // 统计一天的发电时长(分钟) - snprintf(szSql, sizeof(szSql), "select sum(TIMESTAMPDIFF(MINUTE,start_time,stop_time)) from iec_bydwork_param " - "where eqm_code='SBBH1BYQ' and stype=1 " - "and ins_date BETWEEN '2019-01-09 00:00:00' and '2019-01-09 23:59:59'"); - - //统计平均电压,电流 - snprintf(szSql, sizeof(szSql), "select count(*),sum(higth_voltage),sum(higth_current),avg(higth_voltage),avg(higth_current) " - "from iec_bydwork_param where eqm_code = 'SBBH1BYQ' and stype = 1 " - "and ins_date >= '2019-01-09 00:00:00' and ins_date <= '2019-01-09 23:59:59' "); - // select count(*), sum(temper), avg(temper) - // from busi_temper_cac where type = 'A相出线' - // and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59'; - /* - select count(*), sum(temper), avg(temper) - from busi_temper_cac where type = 'B相出线' - and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59' - and eqm_code = 'SBBH31CWG'; --and sensor_id = 'JXHPD001A10000112'; - - select count(*), sum(temper), avg(temper) - from busi_temper_cac where type = 'B相出线' - and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59' - and eqm_code = 'SBBH166CWG'; --and sensor_id = 'JXHPD001A10000112'; - - */ + char szSql[1024] = { 0 }; + + // 统计一天的发电时长(分钟) + snprintf(szSql, sizeof(szSql), "select sum(TIMESTAMPDIFF(MINUTE,start_time,stop_time)) from iec_bydwork_param " + "where eqm_code='SBBH1BYQ' and stype=1 " + "and ins_date BETWEEN '2019-01-09 00:00:00' and '2019-01-09 23:59:59'"); + + //统计平均电压,电流 + snprintf(szSql, sizeof(szSql), "select count(*),sum(higth_voltage),sum(higth_current),avg(higth_voltage),avg(higth_current) " + "from iec_bydwork_param where eqm_code = 'SBBH1BYQ' and stype = 1 " + "and ins_date >= '2019-01-09 00:00:00' and ins_date <= '2019-01-09 23:59:59' "); + // select count(*), sum(temper), avg(temper) + // from busi_temper_cac where type = 'A相出线' + // and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59'; + /* + select count(*), sum(temper), avg(temper) + from busi_temper_cac where type = 'B相出线' + and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59' + and eqm_code = 'SBBH31CWG'; --and sensor_id = 'JXHPD001A10000112'; + + select count(*), sum(temper), avg(temper) + from busi_temper_cac where type = 'B相出线' + and dtime >= '2019-01-09 00:00:00' and dtime <= '2019-01-09 23:59:59' + and eqm_code = 'SBBH166CWG'; --and sensor_id = 'JXHPD001A10000112'; + + */ } diff --git a/src/HTService.cpp b/src/HTService.cpp index 9a1205c..96d228a 100644 --- a/src/HTService.cpp +++ b/src/HTService.cpp @@ -337,12 +337,12 @@ int main(int argc, char* argv[]) ht_pthread_create_background(&thread_handle_linkmgr, thread_listen_proc, NULL); // 链路管理线程 - ht_pthread_create_background(&thread_handle_recv, thread_recv_proc, NULL); + // ht_pthread_create_background(&thread_handle_recv, thread_recv_proc, NULL); // ht_pthread_create_background(&thread_handle_linkmgr, thread_client_proc, NULL); // 链路管理线程 ht_pthread_create_background(&thread_handle_parse, thread_parser_proc, NULL); // 104报文解析线程 ht_pthread_create_background(&thread_handle_timer, thread_Timer_proc, NULL); // 104链路超时管理线程 - ht_pthread_create_background(&thread_handle_active, thread_active_proc, NULL); // 104报文应答线程 + // ht_pthread_create_background(&thread_handle_active, thread_active_proc, NULL); // 104报文应答线程 #endif #ifdef _HT_OPENCV_APP ht_pthread_create_background(&thread_handle_opecvimg, thread_opencv_proc, NULL); // 图片解析线程 diff --git a/src/HTTcpSocket.cpp b/src/HTTcpSocket.cpp index 138382e..02f271f 100644 --- a/src/HTTcpSocket.cpp +++ b/src/HTTcpSocket.cpp @@ -55,16 +55,22 @@ int TTcpSocket::tcpGetSockID() //关闭socket int TTcpSocket::tcpCloseSocket(int sockfd) { - if(sockfd > 0) { + if (sockfd > 0) { vPrtLogMsg(LOG_WARNG, RET_FAIL, "_close sockid=%d ", sockfd); - #ifdef _WIN32 - //if(_close(sockfd) == -1) - if(shutdown(sockfd, 2) == -1) - #else - if(close(sockfd) == -1) - #endif - vPrtLogMsg(LOG_WARNG, RET_FAIL, "_close sockid=%d return:%d:%s",sockfd, errno, strerror(errno)); - return 1; +#ifdef _WIN32 + //if(_close(sockfd) == -1) + if (shutdown(sockfd, 2) == -1) +#else + if (shutdown(sockfd, SHUT_RDWR) == -1) +#endif + vPrtLogMsg(LOG_WARNG, RET_FAIL, "_close sockid=%d return:%d:%s", sockfd, errno, strerror(errno)); + else +#ifdef _WIN32 + closesocket(sockfd); +#else + close(sockfd); +#endif + return 1; } return 0 ; } @@ -396,8 +402,9 @@ int TTcpSocket::tcpRecvBuffer(int sockid, char* pBuffer,int nMaxLength, int time struct timeval st_TimeOut; int isel = 0; - if( sockid <= 0 || pBuffer == NULL) return -1; - while(iTop != nMaxLength) + // if( sockid <= 0 || pBuffer == NULL) return -1; + + while(iTop != nMaxLength) { st_TimeOut.tv_sec = timeout ; st_TimeOut.tv_usec = 0;