You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iec104/src/HTIEC104.cpp

4211 lines
177 KiB
C++

/****************************************************************************
** File name : HTIEC104.h
** Description : define 104 worker thread group
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
//#include <string.h>
#include "HTGlobal.h"
#include "HTIEC104.h"
static const char *_FILE_ = "HTIEC104.cpp";
static FILE *fpIec = NULL; // iec104 config file handle.
static ST_IEC104_CONF g_iec_conf;
static time_t g_Internal_time;
list<ST_RECVPKG> g_list_pack;
mutex g_list_pack_mutex;
list<ST_DB_DATA> g_list_dbset;
mutex g_list_dbset_mutex;
list<ST_IECPOINT_TABLE> g_list_origin;
mutex g_list_origin_mutex;
list<IEC_OBJVAL_NEW> g_list_origin_new;
mutex g_list_origin_mutex_new;
list<std::string> g_list_busi_data;
mutex g_list_busi_data_mutex;
list<ST_IECPOINT_TABLE> g_list_pingce;
mutex g_list_pingce_mutex;
list<ST_IECPOINT_TABLE> g_list_warn;
mutex g_list_warn_mutex;
mutex g_sendno_mutex;
CIEC104::CIEC104()
{
}
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_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());
}
/*************************************************************************
Function iniGetString
Rectives a character string from the specified section in the
specified inifile
Param In :
pszSection : address of section
pszEntry : address of entry
uiBufLen : size of destination buffer
pszFileName: address of inifile name
Param Out :
pszRetBuf : destination buffer
Return Code :
0 : success
<0 : failed
*************************************************************************/
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';
#ifdef _WIN32
if (strcmp(psz1, pszEntry)) continue;
#else
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);
}
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<unsigned int, ST_SADR_MATCH>::value_type(key, stAdr));
mutex_unlock(g_map_sadr_mutex);
}
// 加IEC104业务配置文件数据
static bool iGetIEC104Conf()
{
int iRet = -1, i;
char szTmp[512], szSection[128];
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);
// 总召间隔时间(s)
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_INTERVAL", "action_interval", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get action_interval parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.action_interval = (unsigned int)atoi(szTmp);
// 104原始数据保存时间(s)
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("COMM_SAVE_INTERNAL", "ORIGIN_DATA_SAVE_INTERNAL", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get DATA_SAVE_INTERNAL parameter failed!");
fclose(fpIec);
return false;
}
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<unsigned int, ST_BREAK_EQM_CODE>::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);
2 years ago
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 InitIECENV()
{
memset(&g_IecCtrl, 0x00, sizeof(ST_IEC104_CTRL));
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); // 总召间隔时间更新
}
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_origin_mutex_new);
mutex_create(g_list_busi_data_mutex);
2 years ago
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();
2 years ago
g_list_pingce.clear();
g_list_warn.clear();
InitIECENV();
iGetIEC104Conf();
//InitIECPointTable();
#ifdef _DEBUG
showIEC104Conf();
#endif
}
void IEC104EnvFree()
{
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);
2 years ago
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()
{
mutex_lock(g_IecCtrl_mutex);
g_IecCtrl.last_time = time(NULL);
mutex_unlock(g_IecCtrl_mutex);
}
// 添加报文到解析队列
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);
}
//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);
}
// 添加告警数据队列
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);
}
// 添加断路器断开状态数据队列
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);
}
// 添加原始数据入库队列
static void addOriginDataList(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_origin_mutex);
g_list_origin.push_front(stSetData);
mutex_unlock(g_list_origin_mutex);
}
// 添加原始数据入库队列
static void addOriginDataListNew(const IEC_OBJVAL_NEW &stData)
{
2 years ago
// int i = 0;
// IEC_OBJVAL_NEW stSetData;
2 years ago
// memset(&stSetData, 0x00, sizeof(IEC_OBJVAL_NEW));
// memcpy(&stSetData, &stData, sizeof(IEC_OBJVAL_NEW));
mutex_lock(g_list_origin_mutex_new);
2 years ago
g_list_origin_new.push_front(stData);
mutex_unlock(g_list_origin_mutex_new);
}
2 years ago
// 获取发送序列号
void vAutoSendSeqNo(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);
}
// TX U-Format Message (APCI only)
int SendMsgFormatU(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;
iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, sizeof(ST_APCI));
if (iRet == ErrException)
{
vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", g_IecCtrl.sockid, strerror(errno));
2 years ago
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;
}
// 发送S格式报文
int SendMsgFormatS(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,是固定不变的。
if ((iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, sizeof(ST_APCI))) < 0)
{
vPrtLogMsg(LOG_WARNG, iRet, "send Format S failed with error: %s, errno=%d will close socket", strerror(errno), errno);
2 years ago
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*)&header, sizeof(ST_APCI));
return iRet;
}
// TX I-Format Message (always contains ASDU)
int SendMsgFormatI(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);
if ((iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)buf, len + sizeof(ST_APCI))) < 0)
{
vPrtLogMsg(LOG_WARNG, iRet, "send Format I failed with error: %s, errno=%d will close socket", strerror(errno), errno);
2 years ago
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;
}
int Interrogate(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);
}
/***************************************************************************
** thread_listen_proc 线
**
**
**
***************************************************************************/
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)
{
/*
2 years ago
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);
*/
2 years ago
// vPrtLogMsg(LOG_DEBUG, errno,"slave link waitting connect...accept_fd=%d", accept_fd);
continue;
}
mutex_lock(g_IecCtrl_mutex);
if (g_Tcp.tcpIsConnected(g_IecCtrl.sockid))
{
mutex_unlock(g_IecCtrl_mutex);
vPrtLogMsg(LOG_DEBUG, errno,"Previous link is connected, won't accept accept_fd=%d", accept_fd);
_SLEEP(1000);
continue;
}
2 years ago
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); // 给主链路时间,来处理登录应答.
#ifndef _WIN32
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);
#ifndef _WIN32
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;
}
// 添加104子站服务不能连接的告警消息
void vSetIEC104StationsWarnMesg()
{
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);
}
}
}
// 删除104子站服务不能连接的告警消息
void vDelIEC104StationsWarnMesg()
{
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);
}
}
}
/***************************************************************************
** function name : thread_linkmgr_proc
** deacription : link manager thread
** parameter : none
** return code : NULL
***************************************************************************/
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) ;
#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(); // 链路自动恢复后,处理链路告警:以处理
}
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;
}
/***************************************************************************
** function name : thread_recv_proc
** deacription : 104 parser thread
** parameter : none
** return code : NULL
***************************************************************************/
void* thread_recv_proc(void * arg)
{
unsigned char szBuf[MAX_SBUFF_TCP] = { 0 };
int recv_buflen = 0, pkgLen = 0;
vPrtLogMsg(LOG_DEBUG, 0, "thread_recv_proc = %d startup, sockid=%d...", GETTID(), g_IecCtrl.sockid);
while (g_Running && g_IecCtrl.isConnect)
{
pthread_testcancels();
memset(szBuf, 0x00, sizeof(szBuf));
recv_buflen = -1;
pkgLen = 0;
recv_buflen = g_Tcp.tcpRecvBuffer(g_IecCtrl.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);
2 years ago
g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, MAX_SBUFF_TCP);
mutex_lock(g_IecCtrl_mutex);
g_IecCtrl.isConnect = false;
g_IecCtrl.sockid = -1;
mutex_unlock(g_IecCtrl_mutex);
break;
}
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);
_SLEEP(1000);
2 years ago
continue;
}
mutex_lock(g_IecCtrl_mutex);
g_IecCtrl.last_time = time(NULL);
mutex_unlock(g_IecCtrl_mutex);
if (recv_buflen < (int)sizeof(ST_APCI)) // < 6byte
{
_SLEEP(1000);
continue;
}
if (recv_buflen >= (int)sizeof(ST_APCI) && (szBuf[0] & 0xff) == CMD_START_HEAD) // 0x68H
{
pkgLen = 1 + 1 + (szBuf[1] & 0xff);
if (recv_buflen < pkgLen)
continue;
}
AddParserList(szBuf, pkgLen);
vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_RECV, (unsigned char*)szBuf, pkgLen);
g_Tcp.clear_tcp_buffer(g_IecCtrl.sockid, pkgLen);
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "link exceptiond, thread_recv_proc pthread_exit.");
return NULL;
}
//遥控执行
void vYaoKongExe(unsigned char *msgbuf, unsigned int len)
{
msgbuf[2] = 0x06;
msgbuf[9] = 0x01;
SendMsgFormatI(msgbuf, len);
}
//遥控撤销
void vYaoKongUnexe(unsigned char *msgbuf, unsigned int len)
{
msgbuf[2] = 0x08;
SendMsgFormatI(msgbuf, len);
}
// 遥信值入map
bool bSetPointTableValueYX(unsigned char v, unsigned int adr)
{
IEC_OBJVAL_NEW objVal = { 0 };
objVal.stype = 1;
objVal.dtime = time(NULL);
objVal.ival = v;
objVal.sadr = adr;
addOriginDataListNew(objVal);
2 years ago
bool is_state_opend = false;
unsigned char ovl = 0;
map<unsigned int, ST_IECPOINT_TABLE>::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;
// 遥信量
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 bSetPointTableValueYX(const std::vector<IEC_OBJVAL_NEW>& values)
{
/*
IEC_OBJVAL_NEW objVal = { 0 };
objVal.stype = 1;
objVal.dtime = time(NULL);
objVal.ival = v;
objVal.sadr = adr;
addOriginDataListNew(objVal);
*/
return true;
}
2 years ago
//遥测值入map
bool bSetPointTableValueYC(float v, unsigned int adr)
{
map<unsigned int, ST_IECPOINT_TABLE>::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())
{
2 years ago
vPrtLogMsg(LOG_DEBUG, RET_OK, "bSetPointTableValueYC:%d(0x%04x) set style=%d added OriginDataList", adr, adr, (m_pIter->second).stype);
2 years ago
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);
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
#endif
if ((m_pIter->second).isget == 1 && bCompare(oldval, (m_pIter->second).fval, (m_pIter->second).devrate)) // 是否提取
2 years ago
{
2 years ago
addOriginDataList(m_pIter->second); // 原始数据入库队列
2 years ago
vPrtLogMsg(LOG_DEBUG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f added OriginDataList", adr, adr, (m_pIter->second).fval);
2 years ago
}
2 years ago
//vPrtLogMsg(LOG_DEBUG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f", adr, adr, (m_pIter->second).fval);
2 years ago
}
}
2 years ago
2 years ago
mutex_unlock(g_map_iec_mutex);
return true;
}
bool bSetPointTableValueYC(const std::vector<IEC_OBJVAL_NEW>& values)
{
// Save the origin data into database first
for (std::vector<IEC_OBJVAL_NEW>::const_iterator it = values.begin(); it != values.end(); ++it)
{
addOriginDataListNew(*it);
}
if (g_TConfig.shouldParseBusiData() != 0)
{
// time_t ts = 0;
std::map<unsigned int, IEC_POINT>::const_iterator itPoint;
bool assigned = false;
map<unsigned int, CACHED_DEV_DATA>::iterator itCachedDev;
std::string sql;
list<std::string>::iterator itBusiData;
mutex_lock(g_map_iec_mutex_new);
for (std::vector<IEC_OBJVAL_NEW>::const_iterator it = values.begin(); it != values.end(); ++it)
{
if (it->stype == 1)
{
continue;
}
itPoint = g_map_iec_new.find(it->sadr);
if (itPoint == g_map_iec_new.end() || strlen((const char*)itPoint->second.fieldName) == 0)
{
continue;
}
itCachedDev = g_map_dev_data.find(itPoint->second.sensor_id);
if (itCachedDev == g_map_dev_data.end())
{
continue;
}
assigned = AssignValueToDeviceData(itCachedDev->second, *it);
if (assigned)
{
if (itCachedDev->second.assignedFields == itCachedDev->second.fields.size())
{
sql = BuildSqlForDeviceData(itCachedDev->second);
ResetCachedDeviceData(itCachedDev->second);
mutex_lock(g_list_busi_data_mutex);
itBusiData = g_list_busi_data.insert(g_list_busi_data.end(), std::string());
itBusiData->swap(sql);
mutex_unlock(g_list_busi_data_mutex);
vPrtLogMsg(LOG_DEBUG, 0, "Insert Busi Data into Table %s, sensor_id=%u", (const char*)itCachedDev->second.device->tableName, itCachedDev->second.device->sensor_id);
}
}
}
mutex_unlock(g_map_iec_mutex_new);
2 years ago
}
/*
IEC_OBJVAL_NEW objVal = { 0 };
objVal.stype = 2;
objVal.dtime = time(NULL);
objVal.fval = v;
objVal.sadr = adr;
addOriginDataListNew(objVal);
*/
return true;
}
2 years ago
// I-Formar message decodification I格式帧解码
// msgbuf : asdu_header + asdu_body
// len : asdu length
int DecodeMsgFormatI(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{ numberSQ }
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 IDENTIFICATIONUI8[1..8]<1..255>
// bit 8 7 6 5 4 3 2 1
// 信息对象是否带时标由标识类型的不同序号来区分。
// 控制站将舍弃那些类型标识未被定义的应用服务数据单元
// 类型标识值<0>未用,在本配套标准中定义了 1 至 127 的值128 至 255 未定义。136
// 至 255 可以由此标准的使用者彼此独立的进行定义,仅当使用具有类型标识号为 1 至 127
// 的范围的应用服务数据单元才能达到全部互操作。
std::vector<IEC_OBJVAL_NEW> ycItems;
IEC_OBJVAL_NEW ycItem = { 2, 0 };
time_t ts = time(NULL);
2 years ago
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);
/*
ycItem.stype = 1;
ycItem.dtime = ts;
ycItem.sadr = adr;
ycItem.ival = ps->siq.spi;
ycItems.push_back(ycItem);
*/
2 years ago
pos = sizeof(ST_ASDU_HEADER)+sizeof(SP104);
while (pos < len)
{
adr++;
pi = (SIQ104*)&msgbuf[pos];
//
2 years ago
bSetPointTableValueYX(pi->spi, adr);
/*
ycItem.stype = 1;
ycItem.dtime = ts;
ycItem.sadr = adr;
ycItem.ival = pi->spi;
ycItems.push_back(ycItem);
*/
2 years ago
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);
/*
ycItem.stype = 1;
ycItem.dtime = ts;
ycItem.sadr = adr;
ycItem.ival = ps->siq.spi;
ycItems.push_back(ycItem);
*/
2 years ago
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);
2 years ago
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);
2 years ago
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);
2 years ago
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;
ycItem.sadr = adr;
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, pf->qds.ov, pf->qds.iv, pf->qds.bl);
2 years ago
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;
ycItem.sadr = adr;
ycItem.fval = *val;
ycItems.push_back(ycItem);
2 years ago
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;
ycItem.sadr = adr;
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, pf->qds.ov, pf->qds.iv, pf->qds.bl);
2 years ago
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);
2 years ago
char buf[32];
t56.GetTimeString(buf, sizeof(buf));
2 years ago
bSetPointTableValueYX(ps->siq.spi, adr);
/*
ycItem.stype = 1;
ycItem.dtime = ts;
ycItem.sadr = adr;
ycItem.ival = ps->siq.spi;
ycItems.push_back(ycItem);
*/
2 years ago
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);
CP56Time t56(pf->time);
ycItem.stype = 2;
ycItem.dtime = t56.GetTime();
ycItem.sadr = adr;
ycItem.fval = *val;
ycItems.push_back(ycItem);
2 years ago
char buf[32];
t56.GetTimeString(buf, sizeof(buf));
2 years ago
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) // 激活确认
{
if (g_TConfig.shouldParseBusiData() != 0)
{
ResetAllCachedDeviceData();
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Confirmation, %d.", msgbuf[9] - 20);
}
2 years ago
else if (cause == 10) // 激活结束
{
g_IecCtrl.time_action = ts; // time(NULL);
// SendMsgFormatS(sendno); // 总召唤结束发送S帧确认
if (g_TConfig.shouldParseBusiData() != 0)
{
ResetAllCachedDeviceData();
}
2 years ago
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);
}
2 years ago
return RET_OK;
}
// 发送召唤激活
int SendMsgFormatIAction(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; // 全召
iRet = g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&stPack, stPack.apci.len + 2);
if (iRet == ErrException)
{
vPrtLogMsg(LOG_ERROR, iRet, "send mesg failed, sockid:%d msg:%s will close socket", g_IecCtrl.sockid, strerror(errno));
2 years ago
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; // 总召间隔时间更新
2 years ago
vPrtLogHex(LOG_PACK, g_IecCtrl.sockid, PRT_PACK_SEND, (unsigned char*)&stPack, iRet);
}
return iRet;
}
void DecodeMsgFormatU(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
vPrtLogMsg(LOG_DEBUG, RET_OK, "Send Activation");
2 years ago
SendMsgFormatIAction(CMD_CTL_64H); // 发送总召激活
break;
default:
break;
}
}
// S-Formar message decodification S格式帧解码
void DecodeMsgFormatS(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);
*/
}
/***************************************************************************
** function name : thread_parser_proc
** deacription : 104 parser thread
** parameter : none
** return code : NULL
***************************************************************************/
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)); // 由尾取出
if (pData.pszBuff == NULL) {
mutex_unlock(g_list_pack_mutex);
_SLEEP(MAX_SLEEP_EMPTY * 10);
continue;
}
g_list_pack.pop_back(); // 由尾删除
mutex_unlock(g_list_pack_mutex);
// 解析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;
}
// 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);
}
/***************************************************************************
** function name : thread_origin_proc
** deacription : 104 origin data save database thread
** parameter : none
** return code : NULL
***************************************************************************/
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;
}
/***************************************************************************
** function name : thread_origin_proc_new
** deacription : 104 origin data save database thread
** parameter : none
** return code : NULL
***************************************************************************/
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);
vPrtLogMsg(LOG_DEBUG, 0, "thread_origin_proc_new = %d startup...", GETTID());
while (g_Running)
{
pthread_testcancels();
memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE));
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);
_SLEEP(MAX_SLEEP_EMPTY * 10);
continue;
}
//if (time(NULL) - g_IecCtrl.last_yc_time <= g_iec_conf.save_internal) // 超过设定保存时间间隔时
//{
// g_list_origin_new.clear();
// mutex_unlock(g_list_origin_mutex_new);
// _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_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++)
{
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) // 遥信
{
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);
}
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);
}
pdbHandle->AddInsertRecord(pMySql, szSql);
}
pdbHandle->dbCommit(pMySql);
pdbHandle->dbAutoCommit(pMySql, true);
time_t now = time(NULL);
if (now - g_IecCtrl.last_origin_time >= g_iec_conf.orgin_data_save_internal) // 超过设定保存时间间隔时
{
g_IecCtrl.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);
}
pdbHandle->SetIdleMysql(pMySql);
mutex_unlock(g_list_origin_mutex_new);
_SLEEP(MAX_SLEEP_EMPTY * 10);
}
return NULL;
}
/***************************************************************************
** function name : thread_busi_data_proc
** deacription : 104 business data save database thread
** parameter : none
** return code : NULL
***************************************************************************/
void * thread_busi_data_proc(void * arg)
{
int count = 0, n = 0;
ST_IECPOINT_TABLE pData;
char szSql[512] = { 0 }, szWaringTime[32] = { 0 };
std::string sql;
MYSQL *pMySql = NULL;
vPrtLogMsg(LOG_DEBUG, 0, "thread_busi_data_proc = %d startup...", GETTID());
while (g_Running)
{
pthread_testcancels();
memset(&pData, 0x00, sizeof(ST_IECPOINT_TABLE));
mutex_lock(g_list_busi_data_mutex);
count = g_list_busi_data.size();
n = 0;
if (g_list_busi_data.empty() || g_list_busi_data.size() <= 0) {
mutex_unlock(g_list_busi_data_mutex);
_SLEEP(MAX_SLEEP_EMPTY * 10);
continue;
}
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) {
mutex_unlock(g_list_busi_data_mutex);
_SLEEP(MAX_SLEEP_EMPTY * 5);
continue;
}
pMySql = pdbHandle->GetIdleMySql();
if (pMySql == NULL) {
mutex_unlock(g_list_busi_data_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++)
{
sql.swap(g_list_busi_data.back());
g_list_busi_data.pop_back(); // Remove the tail
// memset(szSql, 0x00, sizeof(szSql));
pdbHandle->AddInsertRecord(pMySql, sql.c_str());
}
pdbHandle->dbCommit(pMySql);
pdbHandle->dbAutoCommit(pMySql, true);
pdbHandle->SetIdleMysql(pMySql);
mutex_unlock(g_list_busi_data_mutex);
_SLEEP(MAX_SLEEP_EMPTY * 10);
}
return NULL;
}
2 years ago
/***************************************************************************
** function name : iGetSadrMatchRecord
** deacription : 104 addr point match list
** parameter : none
** return code : NULL
** relations table: ht_iec104.conf
***************************************************************************/
int iGetSadrMatchRecord(unsigned int sadr, ST_SADR_MATCH &adrList)
{
if(sadr <= 0) return 0 ;
map<unsigned int, ST_SADR_MATCH>::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<unsigned int, ST_SADR_MATCH>::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<unsigned int, ST_IECPOINT_TABLE>::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; //主变绕组温度点位
}
//// 运行工况数据有效性转换
//char * double2String(double value, double dInitValue, char *pStr, int iStrLen)
//{
// memset(pStr, 0x00, iStrLen);
// if (value != dInitValue) sprintf(pStr, "%.4f", value);
// return pStr;
//}
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;
}
// 组织变压器评测数据,iec_bydwork_param
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;
//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);
#ifdef _DEF_HMF_VOLTAGE
// 根据低压侧的电压电流及额定高压侧电压,计算高压侧电流
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);
}
//vPrtLogMsg(LOG_WARNG, RET_FAIL, "INSERT INTO SQL message failed,SQL:%s", szSql);
}
// 保存断路器断开数据记录
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);
}
}
/***************************************************************************
** function name : thread_gis_hold_proc
** deacription :
** parameter : none
** return code : NULL
** relations table: iec_break_param
***************************************************************************/
void * thread_gis_hold_proc(void * arg)
{
ST_IECPOINT_TABLE pData;
ST_BREAK_EQM_CODE stGisRecord;
map<unsigned int, ST_BREAK_EQM_CODE>::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;
}
/***************************************************************************
** function name : thread_pingce_proc
** deacription : 104 pingce data save database thread
** parameter : none
** return code : NULL
** relations table: iec_bydwork_param,iec_breaker_param,transformer_run_status
***************************************************************************/
#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
// 发生信号有变化且发生时间>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);
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 group = 2; group <= 3; 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;
}
}
if (iGetSadrMatchRecord(pData.sadr, adrList) > 0)
{
vBuildByqWorkParam(pData, adrList);
if (adrList.psadr)
{
free((void *)adrList.psadr);
adrList.psadr = NULL;
}
}
pData.sadr = 0 ;
}
}
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)
{
vBuildByqWorkParam(pData, adrList);
if (adrList.psadr)
{
free((void *)adrList.psadr);
adrList.psadr = NULL;
}
}
pData.sadr = 0;
}
}
return NULL;
}
#else
/***************************************************************************
** function name : thread_pingce_proc
** deacription : 104 pingce data save database thread
** parameter : none
** return code : NULL
** relations table: iec_bydwork_param,iec_breaker_param,transformer_run_status
***************************************************************************/
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;
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;
}
#endif
/***************************************************************************
** function name : thread_warn_proc
** deacription : 104 warn data save database thread
** parameter : none
** return code : NULL
***************************************************************************/
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;
}
// 负荷数据数据入库
void dbSet_iec_bydwork_param(ST_IEC_BYQWORK_TABLE *pstWork)
{
/*
bool isChange = false; // 数据是否和最近一次的发生变化了
map<string, ST_BYQ_CACHE>::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;
#else
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;
}
// 运行工况数据入库
//void dbSet_transformer_read_table(ST_IEC_BYQREAD_TABLE *pstRung)
//{
// bool isChange = false; // 数据是否和最近一次的发生变化了
// bool bcurYWei = false, bcurYWen = false, bcurJkyl = false, bcurCkyl = false;
// map<string, ST_BYQ_CACHE>::iterator m_pIter;
// if (!pstRung->eqm_code && strlen((char*)pstRung->eqm_code) <= 0) {
// vPrtLogMsg(LOG_WARNG, RET_FAIL, "dbSet_transformer_read_table: eqm_code is null,please check config file or coding.");
// return;
// }
// mutex_lock(g_map_byq_mutex);
// m_pIter = g_map_byq.find((char*)pstRung->eqm_code);
// if (m_pIter != g_map_byq.end())
// { /*
//#ifdef _SITE_ID_TYPE_INT
// if (pstRung->site_id <= 0)
// pstRung->site_id = (m_pIter->second).SiteID;
//#else
// if (strlen((const char*)pstRung->site_id) <= 0)
// strcpy((char*)pstRung->site_id, (const char*)((m_pIter->second).SiteID));
//#endif
// if (pstRung->dcurYWei > 0 && pstRung->dcurYWei != (m_pIter->second).stLastData.dcurYWei) {
// (m_pIter->second).stLastData.dcurYWei = pstRung->dcurYWei;
// isChange = true;
// }
// else pstRung->dcurYWei = (m_pIter->second).stLastData.dcurYWei;
//
// if (pstRung->dcurYWen > 0 && pstRung->dcurYWen != (m_pIter->second).stLastData.dcurYWen) {
// (m_pIter->second).stLastData.dcurYWen = pstRung->dcurYWen; //覆盖最近一次的数据
// isChange = true; // 发生变化了,需入库
// }
// else pstRung->dcurYWen = (m_pIter->second).stLastData.dcurYWen;
//
// if (pstRung->dcurJkyl > 0 && pstRung->dcurJkyl != (m_pIter->second).stLastData.dcurJkyl) {
// (m_pIter->second).stLastData.dcurJkyl = pstRung->dcurJkyl; //覆盖最近一次的数据
// isChange = true; // 发生变化了,需入库
// }
// else pstRung->dcurJkyl = (m_pIter->second).stLastData.dcurJkyl;
//
// if (pstRung->dcurCkyl > 0 && pstRung->dcurCkyl != (m_pIter->second).stLastData.dcurCkyl) {
// (m_pIter->second).stLastData.dcurCkyl = pstRung->dcurCkyl; //覆盖最近一次的数据
// isChange = true; // 发生变化了,需入库
// }
// else pstRung->dcurCkyl = (m_pIter->second).stLastData.dcurCkyl;
// if (!isChange) return; // 数据未有变化,无需入库操作
// */
// vPrtLogMsg(LOG_DEBUG, RET_OK, "eqm_code:%s Warn_YWei:%.2f Warn_YWen:%.2f Warn_Ckyl:%.2f Warn_Jkyl:%.2f",
// pstRung->eqm_code, (m_pIter->second).dYWei, (m_pIter->second).dYWen, (m_pIter->second).dCkyl, (m_pIter->second).dJkyl);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "eqm_code:%s Curr_YWei:%.2f Curr_YWen:%.2f Curr_Ckyl:%.2f Curr_Jkyl:%.2f",
// pstRung->eqm_code, pstRung->dcurYWei, pstRung->dcurYWen, pstRung->dcurCkyl, pstRung->dcurJkyl);
// // 告警判断
// if (pstRung->dcurYWei > (m_pIter->second).dYWei) bcurYWei = true;
// if (pstRung->dcurYWen > (m_pIter->second).dYWen) bcurYWen = true;
// if (pstRung->dcurJkyl < (m_pIter->second).dJkyl) bcurJkyl = true; // 压力值小于预警值时报警
// if (pstRung->dcurCkyl < (m_pIter->second).dCkyl) bcurCkyl = true; // 压力值小于预警值时报警
//
// // 数据入库
// char szSql[DEF_BUFFER_1K] = { 0 }, szTime[21] = { 0 };
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) {
// mutex_unlock(g_map_byq_mutex);
// return;
// }
// // 实时在线缓存表更新数据
// snprintf(szSql, sizeof(szSql), "update transformer_read_table_cache set d_time=SYSDATE(),oil_temperature='%.2f',"
// "oil_position = '%.2f', cooling_entry_pressure = '%.2f', cooling_exit_pressure = '%.2f', site_eqm_code = '%s' "
// "where site_id = '%s' and eqmid = '%s'",
// pstRung->dcurYWen, pstRung->dcurYWei, pstRung->dcurJkyl, pstRung->dcurCkyl, pstRung->eqm_code, pstRung->site_id, pstRung->eqm_code);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "transformer_read_table_cache: %s", szSql);
// if (!pdbHandle->UpdateRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "UPDATE transformer_read_table_cache failed,SQL:%s", szSql);
// memset(szSql, 0x00, sizeof(szSql));
// snprintf(szSql, sizeof(szSql), "INSERT INTO transformer_read_table_cache(eqmid,d_time,oil_temperature,oil_position,cooling_entry_pressure,"
// "cooling_exit_pressure,site_id,site_eqm_code) "
// "VALUES('%s',SYSDATE(), '%.2f', '%.2f', '%.2f', '%.2f', '%s','%s')",
// pstRung->eqm_code, pstRung->dcurYWen, pstRung->dcurYWei, pstRung->dcurJkyl, pstRung->dcurCkyl, pstRung->site_id, pstRung->eqm_code);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "transformer_read_table_cache: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO transformer_read_table_cache message failed,SQL:%s", szSql);
// }
// }
// // 原始数据入库
// memset(szSql, 0x00, sizeof(szSql));
// snprintf(szSql, sizeof(szSql), "INSERT INTO transformer_read_table(eqmid,d_time,oil_temperature,oil_position,cooling_entry_pressure,"
// "cooling_exit_pressure,site_id) "
// "VALUES('%s',SYSDATE(), '%.2f', '%.2f', '%.2f', '%.2f', '%s')",
// pstRung->eqm_code, pstRung->dcurYWen, pstRung->dcurYWei, pstRung->dcurJkyl, pstRung->dcurCkyl, pstRung->site_id);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "transformer_read_table: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO transformer_read_table message failed,SQL:%s", szSql);
// }
// vTranHostTimeFmt(pstRung->chkTime, szTime);
//
// // 报警入库
// if (bcurYWei) { // 油位告警
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变油位超标:%.2f(L)', '%s', SYSDATE(), '0', '%d', '%s')",
// pstRung->dcurYWei, szTime, pstRung->site_id, pstRung->eqm_code);
//#else
// snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变油位超标:%.2f(L)', '%s', SYSDATE(), '0', '%s', '%s')",
// pstRung->dcurYWei, szTime, pstRung->site_id, pstRung->eqm_code);
//#endif
// vPrtLogMsg(LOG_DEBUG, RET_OK, "dbInsertWaring: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql);
// }
// }
// if (bcurYWen) { // 油温告警
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变油温超标:%.2f(℃)', '%s', SYSDATE(), '0', '%d', '%s')",
// pstRung->dcurYWen, szTime, pstRung->site_id, pstRung->eqm_code);
//#else
// snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变油温超标:%.2f(℃)', '%s', SYSDATE(), '0', '%s', '%s')",
// pstRung->dcurYWen, szTime, pstRung->site_id, pstRung->eqm_code);
//#endif
// vPrtLogMsg(LOG_DEBUG, RET_OK, "dbInsertWaring: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql);
// }
// }
// if (bcurJkyl) { // 进口压力告警
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变冷却水进口压力未达标:%.2f(MPa)', '%s', SYSDATE(), '0', '%d', '%s')",
// pstRung->dcurJkyl, szTime, pstRung->site_id, pstRung->eqm_code);
//#else
// snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变冷却水进口压力未达标:%.2f(MPa)', '%s', SYSDATE(), '0', '%s', '%s')",
// pstRung->dcurJkyl, szTime, pstRung->site_id, pstRung->eqm_code);
//#endif
// vPrtLogMsg(LOG_DEBUG, RET_OK, "dbInsertWaring: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql);
// }
// }
// if (bcurCkyl) { // 出口压力告警
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变冷却水出口压力未达标:%.2f(MPa)', '%s', SYSDATE(), '0', '%d', '%s')",
// pstRung->dcurCkyl, szTime, pstRung->site_id, pstRung->eqm_code);
//#else
// snprintf(szSql, sizeof(szSql), "INSERT INTO busi_eqm_warning(eq_type,gz_type,warning_msg,warning_time,create_time,del_flag,site_id,"
// "eqm_code) "
// "VALUES('1', '9', '主变冷却水出口压力未达标:%.2f(MPa)', '%s', SYSDATE(), '0', '%s', '%s')",
// pstRung->dcurCkyl, szTime, pstRung->site_id, pstRung->eqm_code);
//#endif
// vPrtLogMsg(LOG_DEBUG, RET_OK, "dbInsertWaring: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO busi_eqm_warning message failed,SQL:%s", szSql);
// }
// }
// }
// mutex_unlock(g_map_byq_mutex);
// return;
//}
//void dbSet_iec_breaker_param(ST_IEC_GISBREAK_TABLE *pData)
//{
// // 数据入库
// char szSql[DEF_BUFFER_1K] = { 0 };
// char sTime[21] = { 0 }, eTime[21] = { 0 };
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) return;
//
// vTranHostTimeFmt(pData->d_time, sTime);
//#ifdef _SITE_ID_TYPE_INT
// snprintf(szSql,sizeof(szSql), "INSERT INTO iec_breaker_param(site_id,gis_code,eqm_code,abort_current,abort_voltage,faild_rate,"
// "record_date,ins_date, is_fault,is_break) "
// "VALUES(%d, '%s', '%s', %.2f, %.2f, %.2f, '%s',SYSDATE(), '%d','%d')",
// pData->site_id, pData->eqm_code, pData->eqm_code, pData->abort_current, pData->abort_voltage, pData->faild_rate,
// sTime, pData->is_fault,pData->is_close);
//#else
// snprintf(szSql, sizeof(szSql), "INSERT INTO iec_breaker_param(site_id,gis_code,eqm_code,abort_current,abort_voltage,faild_rate,"
// "record_date,ins_date, is_fault,is_break) "
// "VALUES('%s', '%s', '%s', %.2f, %.2f, %.2f, '%s',SYSDATE(), '%d','%d')",
// pData->site_id, pData->eqm_code, pData->eqm_code, pData->abort_current, pData->abort_voltage, pData->faild_rate,
// sTime, pData->is_fault, pData->is_close);
//#endif
// vPrtLogMsg(LOG_DEBUG, RET_OK, "iec_breaker_param: %s", szSql);
// if (!pdbHandle->InsertRecord((const char *)szSql)) {
// vPrtLogMsg(LOG_ERROR, RET_FAIL, "INSERT INTO iec_breaker_param message failed,SQL:%s", szSql);
// }
// return;
//}
// 刷新设备运行状态: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<unsigned int, ST_IECPOINT_TABLE>::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<unsigned int, ST_IECPOINT_TABLE>::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;
}
// 提取运行工况数据
//static void dbGet_transformer_read_table(ST_IEC_BYQREAD_TABLE &stRung, ST_IEC_BYQWORK_TABLE &stFuHe)
//{
// bool b_byq_close = false, b_byq_fd = false, b_byq_cs = false;
// //bool b_gis_close = false;
// float hCurr = 0, lcurr = 0, hvol = 0, lvol = 0;
// map<unsigned int, ST_IECPOINT_TABLE>::iterator m_pIter;
// mutex_lock(g_map_iec_mutex);
// stFuHe.real_time = time(NULL);
// //stFuHe.start_time = g_IecCtrl.stime > 0 ? g_IecCtrl.stime : time(NULL); // 开始时间
// stRung.chkTime = time(NULL);
// for (m_pIter = g_map_iec.begin(); m_pIter != g_map_iec.end(); m_pIter++)
// {
// if (memcmp((m_pIter->second).eqm_code, stRung.eqm_code, strlen((char*)stRung.eqm_code))) continue;
// if (0 != stringncasecmp((const char*)(m_pIter->second).site_id, (const char*)stRung.site_id, strlen((const char*)stRung.site_id))) continue;
// switch ((m_pIter->second).sadr)
// {
// case 1: case 5: case 9: case 13: // 1号发电机出口开关合位
// if( ( (m_pIter->second).cval & 0xff) == 0x01) b_byq_close = true;
// break;
// case 2: case 6: case 10: case 14: // 1号机组发电换相刀闸合位
// if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_fd = true;
// break;
// case 3: case 7:case 11:case 15: // 1号机组抽水换相刀闸合位
// if (((m_pIter->second).cval & 0xff) == 0x01) b_byq_cs = true;
// break;
// case 4: case 8: case 12: case 16: // 1号机组电气事故
// stFuHe.is_fault = ((m_pIter->second).cval & 0xff);
// break;
// // // GIS的遥信数据
// //case 17: case 18: case 19: // GIS开关合位B相 0:分 1:合
// // if (((m_pIter->second).cval & 0xff) == 0x01) b_gis_close = true;
// // break;
//
// // 以下是遥测量
// case 16385: case 16406: case 16427: case 16448: //主变高压侧A相电流(A)
// break;
// case 16386: case 16407: case 16428: case 16449: //主变高压侧B相电流(A)
// hCurr = (m_pIter->second).fval;
// break;
// case 16387: case 16408: case 16429: case 16450: //主变高压侧C相电流(A)
// break;
//
// case 16388: case 16409: case 16430: case 16451: //主变高压侧A相电压(kv)
// break;
// case 16389: case 16410: case 16431: case 16452: //主变高压侧B相电压(kv)
// hvol = ((m_pIter->second).fval * 1000);
// stFuHe.voltage = ((m_pIter->second).fval * 1000);
// break;
// case 16390: case 16411: case 16432: case 16453: //主变高压侧C相电压(kv)
// break;
//
// case 16391: case 16412: case 16433: case 16454: //机组出口A相电压(kv)
// break;
// case 16392: case 16413: case 16434: case 16455: //机组出口B相电压(kv)
// lvol = ((m_pIter->second).fval * 1000);
// break;
// case 16393: case 16414: case 16435: case 16456: //机组出口C相电压(kv)
// break;
// case 16394: case 16415: case 16436: case 16457: //机组出口A相电流(A)
// break;
// case 16395: case 16416: case 16437: case 16458: //机组出口B相电流(A)
// lcurr = (m_pIter->second).fval;
// break;
// case 16396: case 16417: case 16438: case 16459: //机组出口C相电流(A)
// break;
// case 16397: case 16418: case 16439: case 16460: //主变高压侧上层油温(℃)
// stRung.dcurYWen = (m_pIter->second).fval;
// break;
// case 16398: case 16419: case 16440: case 16461: //主变绕组温度(℃)
// break;
// case 16399: case 16420: case 16441: case 16462: //主变冷却系统进口水压(MPa)
// stRung.dcurJkyl = (m_pIter->second).fval;
// break;
// case 16400: case 16421: case 16442: case 16463: //主变冷却系统出口水压(MPa)
// stRung.dcurCkyl = (m_pIter->second).fval;
// break;
// case 16401: case 16422: case 16443: case 16464: //主变冷却器进口水温(℃)
// break;
// case 16402: case 16423: case 16444: case 16465: //主变冷却器出口水温(℃)
// break;
// case 16403: case 16424: case 16445: case 16466: //主变冷却系统油泵进口油温(℃)
// break;
// case 16404: case 16425: case 16446: case 16467: //主变冷却系统油泵出口油温(℃)
// break;
// case 16405: case 16426: case 16447: case 16468: //主变油位值(待定?)(L)
// stRung.dcurYWei = (m_pIter->second).fval;
// break;
// default:
// //vPrtLogMsg(LOG_WARNG, RET_OK, "this YX addr:%d(0x%04x) not define.", adr, adr);
// ;
// } // end switch
// }// end for
// // mutex_unlock(g_map_iec_mutex);
//
// // 判断开关量
// if (b_byq_close) {
// if (b_byq_fd) stFuHe.state = 0x01; // 发电状态
// else if (b_byq_cs) stFuHe.state = 0x02; // 抽水状态
// else stFuHe.state = 0x03; // 空闲状态
// }
// else stFuHe.state = 0x03; // 空闲状态
// //m_pIter->second.wstate = stFuHe.state;
//
// mutex_unlock(g_map_iec_mutex);
// switch (stFuHe.state & 0xff)
// {
// case 0x02: // 抽水状态
// stFuHe.current = lcurr; // 低压侧电流
// stFuHe.voltage = lvol; // 低压侧电压
// break;
// case 0x03: // 空闲状态,数据无需入库
// g_IecCtrl.stime = 0; // 时间置0
// g_IecCtrl.etime = 0; // 时间置0
// break;
// case 0x01: // 发电状态
// stFuHe.current = hCurr; // 高压侧电流
// stFuHe.voltage = hvol; // 高压侧电压
// break;
// default:;
// }
// stFuHe.stop_time = time(NULL); // 结束时间
//}
//
//// 根据断路器的分组号,获取断路器的开关状态位
////eqm_code : 遥信地址所配置的开关量获取其各A,B,C相的开关量状态位
//// 配置文件中的各断路器A相点表配置其开关量入参eqm_code位A相的编号
////unsigned char cGetGisCloseStatusByEqmCodeA(unsigned int site_id, unsigned char *eqm_code)
//unsigned char cGetGisCloseStatusByEqmCodeA(htype site_id, unsigned char *eqm_code)
//{
// unsigned char cStat = 0;
// map<unsigned int, ST_IECPOINT_TABLE>::iterator m_pIter;
// mutex_lock(g_map_iec_mutex);
// for (m_pIter = g_map_iec.begin(); m_pIter != g_map_iec.end(); m_pIter++)
// {
// if (memcmp((m_pIter->second).eqm_code, eqm_code, strlen((char*)eqm_code))) continue;
//#ifdef _SITE_ID_TYPE_INT
// if ((m_pIter->second).site_id != site_id) continue;
//#else
// if (stringncasecmp((const char*)(m_pIter->second).site_id, (const char*)site_id, strlen((const char*)site_id) != 0)) continue;
//#endif
// switch ((m_pIter->second).sadr)
// {
// case 17: case 18: case 19: // GIS开关合位B相 0:分 1:合
// cStat = ((m_pIter->second).cval & 0xff);
// //if (((m_pIter->second).cval & 0xff) == 0x01) b_gis_close = true;
// break;
// default:;
// }
// }
// mutex_unlock(g_map_iec_mutex);
// return cStat;
//}
//void dbGet_gis_breaker_table(ST_IEC_GISBREAK_TABLE &stGis)
//{
// //bool b_gis_close = false, b_gis_fault = false;
//
// map<unsigned int, ST_IECPOINT_TABLE>::iterator m_pIter;
// mutex_lock(g_map_iec_mutex);
// stGis.d_time = time(NULL);
// for (m_pIter = g_map_iec.begin(); m_pIter != g_map_iec.end(); m_pIter++)
// {
// if (memcmp((m_pIter->second).eqm_code, stGis.eqm_code, strlen((char*)stGis.eqm_code))) continue;
//#ifdef _SITE_ID_TYPE_INT
// if((m_pIter->second).site_id != stGis.site_id) continue;
//#else
// if (stringncasecmp((const char*)(m_pIter->second).site_id, (const char*)stGis.site_id, strlen((const char*)stGis.site_id) != 0)) continue;
//#endif
// switch ((m_pIter->second).sadr)
// {
// case 4: case 8: case 12: case 16: // 1号机组电气事故
// stGis.is_fault = ((m_pIter->second).cval & 0xff);
// break;
// // GIS的遥信数据
// case 17: case 18: case 19: // GIS开关合位B相 0:分 1:合
// stGis.is_close = ((m_pIter->second).cval & 0xff);
// //if (((m_pIter->second).cval & 0xff) == 0x01) b_gis_close = true;
// break;
//
// // 以下是遥测量
// case 16469: // 5001 - 1#电缆线A相电流(A)
// case 16470: // 5001 - 1#电缆线B相电流(A)
// case 16471: // 5001 - 1#电缆线C相电流(A)
// stGis.abort_current = (m_pIter->second).fval;
// break;
// case 16472: // 5003 - 1#电缆线A相电流(A)
// case 16473: // 5003 - 1#电缆线B相电流(A)
// case 16474: // 5003 - 1#电缆线C相电流(A)
// stGis.abort_current = (m_pIter->second).fval;
// break;
// case 16475: // 5051-A相电压(Kv)
// case 16476: // 5051-B相电压(Kv)
// case 16477: // 5051-C相电压(Kv)
// stGis.abort_voltage = ((m_pIter->second).fval * 1000);
// break;
// case 16478: // 5051-A相电流(A)
// case 16479: // 5051-B相电流(A)
// case 16480: // 5051-C相电流(A)
// stGis.abort_current = (m_pIter->second).fval;
// break;
// default:
// //vPrtLogMsg(LOG_WARNG, RET_OK, "this YX addr:%d(0x%04x) not define.", adr, adr);
// stGis.is_close = 0x01; //默认为合状态。
// break;
// } // end switch
// }// end for
// if (stGis.abort_voltage <= 0) {
// m_pIter = g_map_iec.find(16476); // 默认取本设备的电压值,5051-B相电压(Kv)
// if (m_pIter != g_map_iec.end())
// stGis.abort_voltage = ((m_pIter->second).fval * 1000);
// }
// mutex_unlock(g_map_iec_mutex);
// //if (g_IecCtrl.m_gis_count == 0)
// // g_IecCtrl.m_gis_count = 1;
// stGis.faild_rate = 0; // (float)((g_IecCtrl.m_gis_fault_count / g_IecCtrl.m_gis_count) * 100);
//}
/***************************************************************************
** function name : thread_setdb_proc
** deacription : db opration thread and mysql insert...
** parameter : none
** return code : NULL
***************************************************************************/
//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: // 2GIS负荷数据入库 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;
//}
/***************************************************************************
** function name : thread_getdata_proc
** deacription : from g_iec_map get data and add g_list_dbset.
** parameter : none
** return code : NULL
***************************************************************************/
//void *thread_getdata_proc(void *arg)
//{
// vPrtLogMsg(LOG_DEBUG, 0, "thread_getdata_proc = %d startup...", GETTID());
// int i = 0;
// g_IecCtrl.lastTime = time(NULL);
// _SLEEP(1000 * 5);
// while (g_Running)
// {
// pthread_testcancels();
//
// // 发生信号有变化且发生时间>0时立即提取数据加入数据入库队列中
// if (!((g_IecCtrl.b_Signal || g_IecCtrl.m_gis_change) || (time(NULL) - g_IecCtrl.lastTime) > (60 * 5)))
// {
// _SLEEP(100);
// continue;
// }
// if (!g_IecCtrl.isConnect) {
// _SLEEP(100);
// continue;
// }
//
// //g_IecCtrl.stime = 0;
// g_IecCtrl.lastTime = time(NULL);
// for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++)
// {
// // 1运行工况数据入库 transformer_read_table
// ST_IEC_BYQREAD_TABLE stRung;
// ST_IEC_BYQWORK_TABLE stFuHe;
// memset(&stRung, 0x00, sizeof(ST_IEC_BYQREAD_TABLE));
// memset(&stFuHe, 0x00, sizeof(ST_IEC_BYQWORK_TABLE));
// strcpy((char*)stRung.site_id, (const char*)g_iec_conf.site_id);
// strcpy((char*)stFuHe.site_id, (const char*)g_iec_conf.site_id);
// strcpy((char*)stRung.eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode);
// strcpy((char*)stFuHe.eqm_code, (const char*)g_iec_conf.pstByqCode[i].szEqmCode);
// if (g_iec_conf.pstByqCode[i].stime <= 0) {
// g_iec_conf.pstByqCode[i].stime = time(NULL)-10;
// stFuHe.start_time = time(NULL) - 10;
// }
// else {
// stFuHe.start_time = g_iec_conf.pstByqCode[i].etime>0 ? g_iec_conf.pstByqCode[i].etime:time(NULL);
// g_iec_conf.pstByqCode[i].stime = g_iec_conf.pstByqCode[i].etime;
// }
// dbGet_transformer_read_table(stRung, stFuHe);
// // 类型:1-运行工况 2:断路器数据 3:变压器负荷数据
// addDbSetList((char*)&stRung, sizeof(ST_IEC_BYQREAD_TABLE), 0x01);
// //if (stFuHe.current < 100) {
// // vPrtLogMsg(LOG_WARNG, RET_OK, "%s: stype=%d,curr_val=%.2f(A) < 100(A),curr_vol:%.2f(V),not save.",
// // stFuHe.eqm_code, (stFuHe.stype & 0xff), stFuHe.current, stFuHe.voltage);
// // continue;
// //}
// if ((stFuHe.state & 0xff) == 0x01 || (stFuHe.state & 0xff) == 0x02) { // 空闲状态时的数据不入库。2019-01-08
// g_iec_conf.pstByqCode[i].etime = time(NULL);
// stFuHe.stop_time = g_iec_conf.pstByqCode[i].etime;
// addDbSetList((char*)&stFuHe, sizeof(ST_IEC_BYQWORK_TABLE), 0x03);
// }
// if ((stFuHe.state & 0xff) == 0x03) {
// g_iec_conf.pstByqCode[i].stime = time(NULL); // g_iec_conf.pstByqCode[i].etime;
// g_iec_conf.pstByqCode[i].etime = time(NULL);
// }
// }
//
// //if (g_IecCtrl.b_Signal || g_IecCtrl.m_gis_change) // 有主变的开关变化或gis的开关变化时。
// {
// for (i = 0; i < (int)g_iec_conf.iec_break_count; i++)
// {
// // 2GIS负荷数据入库 iec_breaker_param
// ST_IEC_GISBREAK_TABLE stGis;
// memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE));
// strcpy((char*)stGis.site_id, (const char*)g_iec_conf.site_id);
// strcpy((char*)stGis.eqm_code, (const char*)g_iec_conf.pstBrkCode[i].szEqmCodeA);
// dbGet_gis_breaker_table(stGis);
// // 类型:1-运行工况 2:断路器数据 3:变压器负荷数据
// //if ((stGis.is_close & 0xff) == 0x00)
// addDbSetList((char*)&stGis, sizeof(ST_IEC_GISBREAK_TABLE), 0x02);
//
// memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE));
//#ifdef _SITE_ID_TYPE_INT
// stGis.site_id = g_iec_conf.iec_site_id;
//#else
// strcpy((char*)stGis.site_id, (const char*)g_iec_conf.site_id);
//#endif
// strcpy((char*)stGis.eqm_code, (const char*)g_iec_conf.pstBrkCode[i].szEqmCodeB);
// dbGet_gis_breaker_table(stGis);
// stGis.is_close = cGetGisCloseStatusByEqmCodeA(stGis.site_id, g_iec_conf.pstBrkCode[i].szEqmCodeA);
// // 类型:1-运行工况 2:断路器数据 3:变压器负荷数据
// //if ((stGis.is_close & 0xff) == 0x00)
// addDbSetList((char*)&stGis, sizeof(ST_IEC_GISBREAK_TABLE), 0x02);
//
// memset(&stGis, 0x00, sizeof(ST_IEC_GISBREAK_TABLE));
//#ifdef _SITE_ID_TYPE_INT
// stGis.site_id = g_iec_conf.iec_site_id;
//#else
// strcpy((char*)stGis.site_id, (const char*)g_iec_conf.site_id);
//#endif
// strcpy((char*)stGis.eqm_code, (const char*)g_iec_conf.pstBrkCode[i].szEqmCodeC);
// dbGet_gis_breaker_table(stGis);
// stGis.is_close = cGetGisCloseStatusByEqmCodeA(stGis.site_id, g_iec_conf.pstBrkCode[i].szEqmCodeA);
// // 类型:1-运行工况 2:断路器数据 3:变压器负荷数据
// //if ((stGis.is_close & 0xff) == 0x00)
// addDbSetList((char*)&stGis, sizeof(ST_IEC_GISBREAK_TABLE), 0x02);
// }
// g_IecCtrl.m_gis_change = false;
// }
// g_IecCtrl.b_Signal = false;
// _SLEEP(1000);
// }
// return NULL;
//}
/***************************************************************************
** function name : dbGetFaildMaxValue
** deacription : link active thread
** parameter : none
** return code : NULL
***************************************************************************/
//double dbGetFaildMaxValue(const char *site_id, const char *eqm_code)
//{
// double dValue = 0.0;
// char szSql[1024] = { 0 };
//
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// //SELECT a.site_id,b.site_code,a.eqm_code, v.ywei,v.ywen, v.jkyl,v.ckyl FROM busi_site_tree a, transformer_threshold v,busi_offline_transformer_brand b
// //WHERE a.site_id=v.site_id AND a.status = 'A' AND a.type = 'a' AND b.status='A' AND a.eqm_code = v.eqm_code AND a.eqm_code = b.equipment_code AND b.equipment_code=v.eqm_code;
// sprintf(szSql, "select site_id, eqm_code, higth_voltage, higth_current from iec_bydwork_param where site_id='%s' and eqm_code='%s'", site_id, eqm_code);
// printf("=====%s\n", szSql);
// MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
// if (!res) return 0.0;
//
// MYSQL_ROW row = NULL;
// while (row = pdbHandle->GetRecord(res)) {
// printf("site_id = %s eqm_code=%s type=%s\n", row[0], row[1], row[2]);
// }
// pdbHandle->FreeRecord(res);
// printf("\n");
// return dValue;
//}
/***************************************************************************
** function name : thread_Timer_proc
** deacription : Timer_proc thread
** parameter : none
** return code : NULL
***************************************************************************/
void *thread_Timer_proc(void *arg)
{
vPrtLogMsg(LOG_DEBUG, 0, "thread_Timer_proc = %d startup...", GETTID());
while (g_Running)
2 years ago
{
if (!g_IecCtrl.isConnect)
{
_SLEEP(1000);
continue;
}
2 years ago
// 间隔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;
2 years ago
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++;
// t1RTU服务器端启动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);
2 years ago
g_Tcp.tcpCloseSocket(g_IecCtrl.sockid);
g_IecCtrl.isConnect = false;
2 years ago
2 years ago
}
// 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;
}
/***************************************************************************
** function name : thread_active_proc
** deacription : link active thread
** parameter : none
** return code : NULL
***************************************************************************/
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;
g_Tcp.tcpSendBuffer(g_IecCtrl.sockid, (const char*)&header, 6);
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));
//vPrtListCount();
_SLEEP(1000);
}
return NULL;
}
// 获取最近一次变压器的数据
//static void dbGetIECBYQLastData(ST_BYQ_CACHE &pstByq)
//{
// char szSql[256] = { 0 };
// time_t stime = 0;
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) return;
// // 获取最近一次的电压、电流...
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "select stype,start_time,stop_time,higth_voltage,higth_current from iec_bydwork_param where "
// "eqm_code = '%s' and site_id=%d ORDER BY id desc limit 1", pstByq.szEqmCode, pstByq.SiteID);
//#else
// snprintf(szSql, sizeof(szSql), "select stype,start_time,stop_time,higth_voltage,higth_current from iec_bydwork_param where "
// "eqm_code = '%s' and site_id='%s' ORDER BY id desc limit 1", pstByq.szEqmCode, pstByq.SiteID);
//#endif
// MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
// if (!res) return;
//
// MYSQL_ROW row = NULL;
// if (row = pdbHandle->GetRecord(res))
// {
// pstByq.stLastData.stype = atoi(row[0]);
//
// if (row[1] && strlen(row[1]) > 0) {
// memset(szSql, 0x00, sizeof(szSql));
// strncpy(szSql, (const char*)row[1], strlen(row[1]));
// pstByq.stLastData.start_time = strTimeFmt2int(szSql);
// }
//
// if (row[2] && strlen(row[2]) > 0) {
// memset(szSql, 0x00, sizeof(szSql));
// strncpy(szSql, (const char*)row[2], strlen(row[2]));
// pstByq.stLastData.stop_time = strTimeFmt2int(szSql);
// }
// (row[3] && strlen(row[3])) ? (pstByq.stLastData.voltage = atof((const char*)row[3])) : 0;
// (row[4] && strlen(row[4])) ? (pstByq.stLastData.current = atof((const char*)row[4])) : 0;
//
// }
// pdbHandle->FreeRecord(res);
//
// // 获取最近一次的油位,油温,进出口压力值
//#ifdef _SITE_ID_TYPE_INT
// sprintf(szSql, "select oil_temperature,oil_position,cooling_entry_pressure,cooling_exit_pressure "
// "from transformer_read_table where "
// "eqmid = '%s' and site_id=%d ORDER BY id desc limit 1", pstByq.szEqmCode, pstByq.SiteID);
//#else
// snprintf(szSql, sizeof(szSql), "select oil_temperature,oil_position,cooling_entry_pressure,cooling_exit_pressure "
// "from transformer_read_table where "
// "eqmid = '%s' and site_id='%s' ORDER BY id desc limit 1", pstByq.szEqmCode, pstByq.SiteID);
//#endif
// res = pdbHandle->SelectRecord(szSql);
// if (!res) return;
//
// row = NULL;
// if (row = pdbHandle->GetRecord(res))
// {
// pstByq.stLastData.dcurYWen = atof(row[0]);
// pstByq.stLastData.dcurYWei = atof(row[1]);
// pstByq.stLastData.dcurJkyl = atof(row[2]);
// pstByq.stLastData.dcurCkyl = atof(row[3]);
// }
// pdbHandle->FreeRecord(res);
// return;
//}
//// 获取gis数据
//static void dbGetLastDataByEqmCode(unsigned char *pEqmcode)
//{
// int i = 0;
// char szSql[256] = { 0 };
// string strKey = "";
// time_t stime = 0;
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) return;
//
// snprintf(szSql, sizeof(szSql), "select site_id,abort_voltage,abort_current,faild_rate,is_fault,record_date from iec_breaker_param "
// "where eqm_code = '%s' ORDER BY id desc limit 1", pEqmcode);
//
// MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
// if (!res) return;
// strKey = (char*)pEqmcode;
// MYSQL_ROW row = NULL;
// if (row = pdbHandle->GetRecord(res))
// {
// ST_GIS_IEC104_DATA stGis;
// memset(&stGis, 0x00, sizeof(ST_GIS_IEC104_DATA));
//
// strcpy((char*)stGis.szEqmCode, (char*)pEqmcode);
//#ifdef _SITE_ID_TYPE_INT
// (row[0] && strlen(row[0])) ? (stGis.SiteID = atoi((const char*)row[0])) : 0; // site_id
//#else
// if (row[0] && strlen(row[0]) > 0) {
// strncpy((char*)stGis.SiteID, row[0], strlen(row[0]));
// }
//#endif
// (row[1] && strlen(row[1])) ? (stGis.stLastData.voltage = atof((const char*)row[1])) : 0;
// (row[2] && strlen(row[2])) ? (stGis.stLastData.current = atof((const char*)row[2])) : 0;
// (row[3] && strlen(row[3])) ? (stGis.stLastData.failed_rate = atof((const char*)row[3])) : 0;
// (row[4] && strlen(row[4])) ? (stGis.stLastData.is_fault = atoi((const char*)row[4])) : 0;
// if (row[5] && strlen(row[5]) > 0) {
// memset(szSql, 0x00, sizeof(szSql));
// strncpy(szSql, (const char*)row[5], strlen(row[5]));
// stGis.stLastData.record_date = strTimeFmt2int(szSql);
// }
// mutex_lock(g_map_gis_104_mutex);
// g_map_gis_104.insert(map<string, ST_GIS_IEC104_DATA>::value_type(strKey, stGis));
// mutex_unlock(g_map_gis_104_mutex);
// }
// pdbHandle->FreeRecord(res);
// return;
//}
// 获取最近一次断路器的数据
//static void dbGetIECGISLastData()
//{
// int i = 0;
// for (i = 0; i < (int)g_iec_conf.iec_break_count; i++)
// {
// dbGetLastDataByEqmCode(g_iec_conf.pstBrkCode[i].szEqmCodeA);
// dbGetLastDataByEqmCode(g_iec_conf.pstBrkCode[i].szEqmCodeB);
// dbGetLastDataByEqmCode(g_iec_conf.pstBrkCode[i].szEqmCodeC);
// }
// return;
//}
// 打印GIS最近一次104上传数据
//static void vPrtIECGISLastData()
//{
// map<string, ST_GIS_IEC104_DATA>::iterator m_pIter;
// m_pIter = g_map_gis_104.begin();
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print GIS Last Data ----------");
// while (m_pIter != g_map_gis_104.end())
// {
//#ifdef _SITE_ID_TYPE_INT
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-4d %-10s %.3f %.3f %.3f %1d %u", (m_pIter->second).SiteID, (m_pIter->second).szEqmCode,
//#else
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-s %.3f %.3f %.3f %1d %u", (m_pIter->second).szEqmCode,
//#endif
// (m_pIter->second).stLastData.voltage, (m_pIter->second).stLastData.current,
// (m_pIter->second).stLastData.failed_rate, (m_pIter->second).stLastData.is_fault, (m_pIter->second).stLastData.record_date);
// m_pIter++;
// }
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- gis_last_data_size:%d-----------", g_map_gis_104.size());
// return;
//}
// 设置主变的油位信息体地址
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;
}
//// 获取站点主变设备对应关系及阈值
//bool bGetByqCacheRelation(unsigned char *pszEqmCode, ST_BYQ_CACHE *pstData)
//{
// if (!pszEqmCode) return false;
// map<string, ST_BYQ_CACHE>::iterator m_pIter;
// mutex_lock(g_map_byq_mutex);
// m_pIter = g_map_byq.find((char*)pszEqmCode);
// if (m_pIter != g_map_byq.end())
// {
// memcpy(pstData, &(m_pIter->second), sizeof(ST_BYQ_CACHE));
// //g_map_request_mec_rsp.erase(m_pIter) ;
// mutex_unlock(g_map_byq_mutex);
// return true;
// }
// mutex_unlock(g_map_byq_mutex);
// vPrtLogMsg(LOG_WARNG, RET_OK, "Can't found EqmCode:%s on BYQ cache relation table,map_size:%d", pszEqmCode, g_map_byq.size());
// return false;
//}
/***************************************************************************
** function name : dbGetGISCacheData
** deacription : get gis define value & site_id-->site_code relation.
** parameter : none
** return code : NULL
***************************************************************************/
//void dbGetGISCacheData(void)
//{
// char szSql[1024] = { 0 };
//
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) return;
//
// snprintf(szSql, sizeof(szSql), "SELECT c.site_id,b.des, b.cac_number, b.eqm_code, c.picval FROM gis_sbjc a, gis_tree b, gis_threshold c "
// "WHERE a.status = 'A' AND a.type = '6' AND b.type = '6' AND a.id = b.eqm_id AND b.eqm_code = c.eqm_code");
//
// MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
// if (!res) return;
//
// MYSQL_ROW row = NULL;
// while (row = pdbHandle->GetRecord(res))
// {
// ST_GIS_CACHE stGis;
// string strKey = "";
// memset(&stGis, 0x00, sizeof(ST_GIS_CACHE));
//#ifdef _STIE_ID_TYPE_INT
// stGis.SiteID = atoi(row[0]);
//#else
// if (row[0] && strlen(row[0]) > 0) {
// strncpy((char*)stGis.SiteID, (const char*)row[0], strlen(row[0]));
// }
//#endif
// if (row[1] && strlen(row[1]) > 0) {
// strncpy((char*)stGis.name_des, (const char*)row[1], sizeof(stGis.name_des));
// }
// if (row[2] && strlen(row[2]) > 0) {
// strncpy((char*)stGis.szSersorID, (const char*)row[2], sizeof(stGis.szSersorID));
// strKey = (char*)stGis.szSersorID;
// }
// if (row[3] && strlen(row[3]) > 0) {
// strncpy((char*)stGis.szEqmCodeID, (const char*)row[3], sizeof(stGis.szEqmCodeID));
// }
// (row[4] && strlen(row[4])) ? (stGis.dNum = atof((const char*)row[4])) : 0;
//
// mutex_lock(g_map_gis_mutex);
// g_map_gis.insert(map<string, ST_GIS_CACHE>::value_type(strKey, stGis));
// mutex_unlock(g_map_gis_mutex);
// }
// pdbHandle->FreeRecord(res);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---get_gis_size:%d---", g_map_gis.size());
// return;
//}
// 获取GIS设备对应关系及阈值
//bool bGetGisCacheRelation(unsigned char *pszSersorid, ST_GIS_CACHE *pstData)
//{
// if (!pszSersorid) return false;
// map<string, ST_GIS_CACHE>::iterator m_pIter;
// mutex_lock(g_map_gis_mutex);
// m_pIter = g_map_gis.find((char*)pszSersorid);
// if (m_pIter != g_map_gis.end())
// {
// memcpy(pstData, &(m_pIter->second), sizeof(ST_GIS_CACHE));
// //g_map_request_mec_rsp.erase(m_pIter) ;
// mutex_unlock(g_map_gis_mutex);
// return true;
// }
// mutex_unlock(g_map_gis_mutex);
// vPrtLogMsg(LOG_WARNG, RET_OK, "Can't found SersorID:%s on GIS cache relation table,map_size:%d", pszSersorid, g_map_gis.size());
// return false;
//}
// 打印GIS缓存数据
//void vPrtGisCacheRelation(void)
//{
// map<string, ST_GIS_CACHE>::iterator m_pIter;
// m_pIter = g_map_gis.begin();
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print GIS Relation----------");
// while (m_pIter != g_map_gis.end())
// {
// // c.site_id, b.des, b.cac_number, b.eqm_code, c.tpsb_dl
//#ifdef _SITE_ID_TYPE_INT
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-4d %-.5f %18s %16s", (m_pIter->second).SiteID,
//#else
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-.5f %18s %16s",
//#endif
// (m_pIter->second).dNum, (m_pIter->second).szSersorID, (m_pIter->second).szEqmCodeID);
// m_pIter++;
// }
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- GIS_size:%d-----------", g_map_gis.size());
// return;
//}
/***************************************************************************
** function name : dbGetBLQCacheData
** deacription : get BLQ define value & site_id-->site_code relation.
** parameter : none
** return code : NULL
***************************************************************************/
//void dbGetBLQCacheData(void)
//{
// char szSql[1024] = { 0 };
//
// CDBMySQL *pdbHandle = CDBMySQL::Instance();
// if (!pdbHandle) return;
//
// snprintf(szSql, sizeof(szSql), "SELECT c.site_id,b.des, b.cac_number, b.eqm_code, c.tpsb_dl FROM arrester_sbjc a, arrester_tree b, arrester_threshold c "
// "WHERE a.status = 'A' AND a.type = '5' AND b.type = '5' AND a.id = b.eqm_id AND b.eqm_code = c.eqm_code");
//
// MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
// if (!res) return;
//
// MYSQL_ROW row = NULL;
// while (row = pdbHandle->GetRecord(res))
// {
// ST_BLQ_CACHE stBlq;
// string strKey = "";
// memset(&stBlq, 0x00, sizeof(ST_BLQ_CACHE));
//#ifdef _SITE_ID_TYPE_INT
// stBlq.SiteID = atoi(row[0]);
//#else
// if (row[0] && strlen(row[0]) > 0) {
// strncpy((char*)stBlq.SiteID, (const char*)row[0], strlen(row[0]));
// }
//#endif
// if (row[1] && strlen(row[1]) > 0) {
// strncpy((char*)stBlq.name_des, (const char*)row[1], sizeof(stBlq.name_des));
// }
// if (row[2] && strlen(row[2]) > 0) {
// strncpy((char*)stBlq.szSersorID, (const char*)row[2], sizeof(stBlq.szSersorID));
// strKey = (char*)stBlq.szSersorID;
// }
// if (row[3] && strlen(row[3]) > 0) {
// strncpy((char*)stBlq.szEqmCodeID, (const char*)row[3], sizeof(stBlq.szEqmCodeID));
// }
// (row[4] && strlen(row[4])) ? (stBlq.dMaxDL = atof((const char*)row[4])) : 0;
//
// mutex_lock(g_map_blq_mutex);
// g_map_blq.insert(map<string, ST_BLQ_CACHE>::value_type(strKey, stBlq));
// mutex_unlock(g_map_blq_mutex);
// }
// pdbHandle->FreeRecord(res);
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---get_BLQ_size:%d---", g_map_blq.size());
// return;
//}
// 获取BLQ设备对应关系及阈值
//bool bGetBlqCacheRelation(unsigned char *pszSersorid, ST_BLQ_CACHE *pstData)
//{
// if (!pszSersorid) return false;
// map<string, ST_BLQ_CACHE>::iterator m_pIter;
// mutex_lock(g_map_blq_mutex);
// m_pIter = g_map_blq.find((char*)pszSersorid);
// if (m_pIter != g_map_blq.end())
// {
// memcpy(&pstData, &(m_pIter->second), sizeof(ST_BYQ_CACHE));
// //g_map_request_mec_rsp.erase(m_pIter) ;
// mutex_unlock(g_map_blq_mutex);
// return true;
// }
// mutex_unlock(g_map_blq_mutex);
// vPrtLogMsg(LOG_WARNG, RET_OK, "Can't found SersorID:%s on BLQ cache relation table,map_size:%d", pszSersorid, g_map_blq.size());
// return false;
//}
// 打印BLQ缓存数据
//void vPrtBlqCacheRelation(void)
//{
// map<string, ST_BLQ_CACHE>::iterator m_pIter;
// m_pIter = g_map_blq.begin();
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print BLQ Relation----------");
// while (m_pIter != g_map_blq.end())
// {
// // c.site_id, b.des, b.cac_number, b.eqm_code, c.tpsb_dl
//#ifdef _SITE_ID_TYPE_INT
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-4d %-.5f %18s %16s %s", (m_pIter->second).SiteID,
//#else
// vPrtLogMsg(LOG_DEBUG, RET_OK, "%-.5f %18s %16s %s",
//#endif
// (m_pIter->second).dMaxDL, (m_pIter->second).szSersorID, (m_pIter->second).szEqmCodeID,
// (m_pIter->second).name_des);
// m_pIter++;
// }
// vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- BLQ_size:%d-----------", g_map_blq.size());
// return;
//}
// 统计发电、抽水时间
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';
*/
}