/****************************************************************************
* * 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 ) ;
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 ) ;
mutex_create ( g_list_pingce_mutex ) ;
mutex_create ( g_list_warn_mutex ) ;
g_list_pack . clear ( ) ;
g_list_dbset . clear ( ) ;
g_list_origin . clear ( ) ;
g_list_origin_new . clear ( ) ;
g_list_busi_data . clear ( ) ;
g_list_pingce . clear ( ) ;
g_list_warn . clear ( ) ;
InitIECENV ( ) ;
iGetIEC104Conf ( ) ;
//InitIECPointTable();
# 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 ) ;
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 )
{
// int i = 0;
// IEC_OBJVAL_NEW stSetData;
// memset(&stSetData, 0x00, sizeof(IEC_OBJVAL_NEW));
// memcpy(&stSetData, &stData, sizeof(IEC_OBJVAL_NEW));
mutex_lock ( g_list_origin_mutex_new ) ;
g_list_origin_new . push_front ( stData ) ;
mutex_unlock ( g_list_origin_mutex_new ) ;
}
// 获取发送序列号
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 ) ) ;
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 ) ;
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 ) ;
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 )
{
/*
mutex_lock ( g_IecCtrl_mutex ) ;
g_Tcp . tcpCloseSocket ( g_IecCtrl . sockid ) ;
g_IecCtrl . last_time = 0 ;
g_IecCtrl . sockid = - 1 ;
g_IecCtrl . isConnect = false ;
mutex_unlock ( g_IecCtrl_mutex ) ;
_SLEEP ( 1000 ) ;
*/
// vPrtLogMsg(LOG_DEBUG, errno,"slave link waitting connect...accept_fd=%d", accept_fd);
continue ;
}
mutex_lock ( g_IecCtrl_mutex ) ;
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 ;
}
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 ) ;
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 ) ;
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 ) ;
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 ;
}
//遥测值入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 ( ) )
{
vPrtLogMsg ( LOG_DEBUG , RET_OK , " bSetPointTableValueYC:%d(0x%04x) set style=%d added OriginDataList " , adr , adr , ( m_pIter - > second ) . stype ) ;
if ( ( ( m_pIter - > second ) . stype & 0xff ) = = 2 )
{
// 遥测量
oldval = ( m_pIter - > second ) . fval ;
( m_pIter - > second ) . dtime = time ( NULL ) ;
( m_pIter - > second ) . fval = getChangeUnit ( ( m_pIter - > second ) . unit , ( m_pIter - > second ) . sysunit , v ) ; // 单位转换
if ( ( ( m_pIter - > second ) . eqm_type & 0xff ) = = 1 )
( m_pIter - > second ) . wstate = cGetByqDeviceState ( ( m_pIter - > second ) . eqm_code ) ;
else ( m_pIter - > second ) . wstate = cGetCurrentWorkState ( ( m_pIter - > second ) . eqm_code ) ; // 获取工作状态
if ( strlen ( ( char * ) ( m_pIter - > second ) . fieldname ) > 0 ) {
addWarningTableList ( m_pIter - > second ) ;
}
# 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 ) ) // 是否提取
{
addOriginDataList ( m_pIter - > second ) ; // 原始数据入库队列
vPrtLogMsg ( LOG_DEBUG , RET_OK , " YC addr:%d(0x%04x) set val=%.4f added OriginDataList " , adr , adr , ( m_pIter - > second ) . fval ) ;
}
//vPrtLogMsg(LOG_DEBUG, RET_OK, "YC addr:%d(0x%04x) set val=%.4f", adr, adr, (m_pIter->second).fval);
}
}
mutex_unlock ( g_map_iec_mutex ) ;
return true ;
}
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 ) ;
}
/*
IEC_OBJVAL_NEW objVal = { 0 } ;
objVal . stype = 2 ;
objVal . dtime = time ( NULL ) ;
objVal . fval = v ;
objVal . sadr = adr ;
addOriginDataListNew ( objVal ) ;
*/
return true ;
}
// 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 { number 、 SQ }
number = N = 数 目 : = UI7 [ 1. .7 ] < 0. .127 >
< 0 > : = 应 用 服 务 数 据 单 元 不 含 信 息 对 象
< 1. .127 > : = 应 用 服 务 数 据 单 元 信 息 元 素 ( 单 个 信 息 元 素 或 同 类 信 息 元 素 组 合 ) 的 数 目
SQ = 单 个 或 者 顺 序 : = BS1 [ 8 ] < 0. .1 >
< 0 > : = 寻 址 同 一 种 类 型 的 许 多 信 息 对 象 中 单 个 的 信 息 元 素 或 者 信 息 元 素 的 集 合
< 1 > : = 寻 址 ASDU 单 个 信 息 对 象 中 顺 序 的 单 个 信 息 元 素 信 息 元 素 的 同 类 集 合
SQ < 0 > 和 N < 0. .127 > ∶ = 信 息 对 象 的 数 目 I ( 一 个 地 址 + 一 个 元 素 ) * N
SQ < 1 > 和 N < 0. .127 > ∶ = 每 个 应 用 服 务 数 据 单 元 中 单 个 对 象 的 信 息 元 素 或 者 信 息 元 素 的
集 合 的 数 目 j ( 一 个 地 址 , 后 接 连 续 N 个 元 素 )
SQ 位 规 定 寻 址 后 续 信 息 对 象 或 单 个 信 息 元 素 / 信 息 元 素 集 合 的 方 法 。
SQ : = 0 由 信 息 对 象 地 址 寻 址 的 单 个 信 息 元 素 或 信 息 元 素 集 合 。 应 用 服 务 数 据 单
元 可 以 由 一 个 或 者 多 个 同 类 的 信 息 对 象 所 组 成 。 数 目 N 是 一 个 二 进 制 数 , 它 定 义 了 信 息 对
象 的 数 目 。
SQ : = 1 单 个 信 息 元 素 或 者 信 息 元 素 同 类 集 合 的 序 列 ( 即 同 一 种 格 式 测 量 值 ) 由 信
息 对 象 地 址 来 寻 址 ( 见 IEC 60870 - 5 - 3 中 的 5.1 .5 ) , 信 息 对 象 地 址 是 顺 序 单 个 信 息 元 素 或 者 信
息 元 素 集 合 的 第 一 个 信 息 元 素 或 者 集 合 的 地 址 。 后 续 单 个 信 息 元 素 或 者 信 息 元 素 集 合 的 地
址 是 从 这 个 地 址 起 顺 序 加 1 。 数 目 N 是 一 个 二 进 制 数 , 它 定 义 了 单 个 信 息 元 素 或 者 信 息 元
素 集 合 的 数 目 。 在 顺 序 单 个 信 息 元 素 或 者 信 息 元 素 集 合 的 情 况 下 每 个 应 用 服 务 数 据 单 元 仅
安 排 一 个 信 息 对 象 .
*/
header = ( ST_ASDU_HEADER * ) msgbuf ;
num = header - > qual & 0x7F ; // number of objects. 数据元素个数
if ( header - > qual & 0x80 ) // sequence of objects ? 限定词,第一位:1=报文包含信息数据,0=不含信息数据
seq = true ;
/*
传 送 原 因 = CAUSE OF TRANSMISSION : = CP16 { Cause , P / N , T , Originator Address ( opt ) }
其 中 Cause : = UI6 [ 1. .6 ] < 0. .63 >
< 0 > : = 未 定 义
< 1. .63 > : = 传 送 原 因 序 号
< 1. .47 > : = 本 配 套 标 准 的 标 准 定 义 ( 兼 容 范 围 ) 见 表 14
< 48. .63 > : = 专 用 范 围
P / N ∶ = BS1 [ 7 ] < 0. .1 >
< 0 > ∶ = 肯 定 确 认
< 1 > ∶ = 否 定 确 认
T = test : = BS1 [ 8 ] < 0. .1 >
< 0 > : = 未 试 验
< 1 > : = 试 验
Originator address = 源 发 者 地 址 : = UI8 [ 9. .16 ]
< 0 > : = 缺 省 值
< 1. .255 > : = 源 发 者 地 址 号
*/
cause = header - > tx_cause1 ; // cause of tx.传送原因[1]
/* 公共地址 : = UI16[1..16]<0..65535>
其 中 < 0 > : = 未 用
< 1. .65534 > : = 站 地 址
< 65535 > : = 全 局 地 址 */
asdu = header - > commom_asdu2 < < 8 ;
asdu | = header - > commom_asdu1 ;
if ( asdu ! = g_iec_conf . iec_global_addr ) {
vPrtLogMsg ( LOG_ERROR , RET_FAIL , " Recv Common Address=0x%04x(%d), Dest Common Address=0x%04x(%d), Plase Checking Config! " , asdu , asdu , g_iec_conf . iec_global_addr , g_iec_conf . iec_global_addr ) ;
}
vPrtLogMsg ( LOG_DEBUG , RET_OK , " ASDU Common Address=0x%04x(%d) TypeID=%d Count=%d Cause=%d(0x%02x) seq=%d " , asdu , asdu , header - > type , num , cause , cause , seq ) ;
// type identification
// 第一个八位位组为类型标识(图 11), 它定义了后续信息对象的结构、类型和格式。
// 类型标识定义如下:
// 类型标识= TYPE IDENTIFICATION: = UI8[1..8]<1..255>
// bit 8 7 6 5 4 3 2 1
// 信息对象是否带时标由标识类型的不同序号来区分。
// 控制站将舍弃那些类型标识未被定义的应用服务数据单元
// 类型标识值<0>未用,在本配套标准中定义了 1 至 127 的值, 128 至 255 未定义。136
// 至 255 可以由此标准的使用者彼此独立的进行定义,仅当使用具有类型标识号为 1 至 127
// 的范围的应用服务数据单元才能达到全部互操作。
std : : vector < IEC_OBJVAL_NEW > ycItems ;
IEC_OBJVAL_NEW ycItem = { 2 , 0 } ;
time_t ts = time ( NULL ) ;
switch ( header - > type & 0xff )
{
case 1 : // Single-point information
SIQ104 * pi ;
if ( seq ) // 有序数据,即信息体地址[3]+data[1]+data[1]+...
{
SP104 * ps = ( SP104 * ) & msgbuf [ sizeof ( ST_ASDU_HEADER ) ] ;
adr = ps - > addr2 < < 16 | ps - > addr1 < < 8 | ps - > addr0 ;
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SP_%d: val:%d Valid: %d Blocked: %d " , header - > type , adr , ps - > siq . spi , ps - > siq . iv , ps - > siq . bl ) ;
bSetPointTableValueYX ( ps - > siq . spi , adr ) ;
/*
ycItem . stype = 1 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . ival = ps - > siq . spi ;
ycItems . push_back ( ycItem ) ;
*/
pos = sizeof ( ST_ASDU_HEADER ) + sizeof ( SP104 ) ;
while ( pos < len )
{
adr + + ;
pi = ( SIQ104 * ) & msgbuf [ pos ] ;
//
bSetPointTableValueYX ( pi - > spi , adr ) ;
/*
ycItem . stype = 1 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . ival = pi - > spi ;
ycItems . push_back ( ycItem ) ;
*/
if ( pi - > spi )
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SP_%d: val:%d Valid: %d Blocked: %d " , header - > type , adr , pi - > spi , pi - > iv , pi - > bl ) ;
pos + + ;
}
if ( cause = = 3 ) SendMsgFormatS ( sendno ) ; // 突发上送之后发送S帧确认
}
else { // 数据格式,即信息体地址[3]+data[1]+信息体地址[3]+data[1]+信息体地址[3]+data[1]+...
pos = sizeof ( ST_ASDU_HEADER ) ;
while ( pos < len )
{
SP104 * ps = ( SP104 * ) & msgbuf [ pos ] ;
adr = ps - > addr2 < < 16 | ps - > addr1 < < 8 | ps - > addr0 ;
bSetPointTableValueYX ( ps - > siq . spi , adr ) ;
/*
ycItem . stype = 1 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . ival = ps - > siq . spi ;
ycItems . push_back ( ycItem ) ;
*/
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SP_%d: val:%d Valid: %d Blocked: %d " , header - > type , adr , ps - > siq . spi , ps - > siq . iv , ps - > siq . bl ) ;
pos + = sizeof ( SP104 ) ;
}
}
break ;
case 9 : // 短整数,测量值,归一化值
pos = sizeof ( ST_ASDU_HEADER ) ;
if ( seq )
{ // 连续的值序列,常见于总召报文,即: 3位信息地址+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]+[2字节的值+1字节的品质位]...
SH104 * pf = ( SH104 * ) & msgbuf [ pos ] ;
adr = pf - > addr2 < < 16 | pf - > addr1 < < 8 | pf - > addr0 ;
short * val = ( short * ) & pf - > val [ 0 ] ;
bSetPointTableValueYC ( * val , adr ) ;
ycItem . stype = 2 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . fval = * val ;
ycItems . push_back ( ycItem ) ;
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d " , header - > type , adr , adr , * val , pf - > qds . ov , pf - > qds . iv , pf - > qds . bl ) ;
pos + = sizeof ( SH104 ) ;
adr + + ;
while ( pos < len )
{
SHP104 * pfv = ( SHP104 * ) & msgbuf [ pos ] ;
short * val = ( short * ) & pfv - > val [ 0 ] ;
bSetPointTableValueYC ( * val , adr ) ;
ycItem . stype = 2 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . fval = * val ;
ycItems . push_back ( ycItem ) ;
if ( * val )
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d " , header - > type , adr , adr , * val , pfv - > qds . ov , pfv - > qds . iv , pfv - > qds . bl ) ;
pos + = sizeof ( SHP104 ) ;
adr + + ;
}
}
else { // 当有变化量时,连续的值序列,即: 3位信息地址+[2字节的值+1字节的品质位]+3位信息地址+[2字节的值+1字节的品质位]+...
while ( pos < len )
{
SH104 * pf = ( SH104 * ) & msgbuf [ pos ] ;
adr = pf - > addr2 < < 16 | pf - > addr1 < < 8 | pf - > addr0 ;
short * val = ( short * ) & pf - > val [ 0 ] ;
bSetPointTableValueYC ( * val , adr ) ;
ycItem . stype = 2 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . fval = * val ;
ycItems . push_back ( ycItem ) ;
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SFP_%d(0x%04x): val:%d OFlow: %d Valid: %d Blocked: %d " , header - > type , adr , adr , * val , pf - > qds . ov , pf - > qds . iv , pf - > qds . bl ) ;
pos + = sizeof ( SH104 ) ;
}
}
break ;
case 13 : // Measure value, short floating point value 短浮点数测量值
pos = sizeof ( ST_ASDU_HEADER ) ;
if ( seq )
{ // 连续的值序列,常见于总召报文,即: 3位信息地址+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]+[4字节的值+1字节的品质位]...
SFP104 * pf = ( SFP104 * ) & msgbuf [ pos ] ;
adr = pf - > addr2 < < 16 | pf - > addr1 < < 8 | pf - > addr0 ;
float * val = ( float * ) & pf - > val [ 0 ] ;
bSetPointTableValueYC ( * val , adr ) ;
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 ) ;
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 ) ;
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 ) ;
pos + = sizeof ( SFP104 ) ;
}
}
break ;
case 30 : // Single-point information with time tag CP56Time2a 带CP56时标的单点信息
pos = sizeof ( ST_ASDU_HEADER ) ;
while ( pos < len )
{
SP104_T * ps = ( SP104_T * ) & msgbuf [ pos ] ;
adr = ps - > addr2 < < 16 | ps - > addr1 < < 8 | ps - > addr0 ;
CP56Time t56 ( ps - > time ) ;
char buf [ 32 ] ;
t56 . GetTimeString ( buf , sizeof ( buf ) ) ;
bSetPointTableValueYX ( ps - > siq . spi , adr ) ;
/*
ycItem . stype = 1 ;
ycItem . dtime = ts ;
ycItem . sadr = adr ;
ycItem . ival = ps - > siq . spi ;
ycItems . push_back ( ycItem ) ;
*/
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SP_%d: val:%d Valid: %d Blocked: %d time:%s " , header - > type , adr , ps - > siq . spi , ps - > siq . iv , ps - > siq . bl , buf ) ;
pos + = sizeof ( SP104_T ) ;
}
if ( cause = = 3 ) SendMsgFormatS ( sendno ) ; // 突发上送之后发送S帧确认
break ;
case 36 : // Measure value, short float point value w/CP56Time2a 带CP56时标的短浮点测量值
pos = sizeof ( ST_ASDU_HEADER ) ;
while ( pos < len )
{
SFP104_T * pf = ( SFP104_T * ) & msgbuf [ pos ] ;
adr = pf - > addr2 < < 16 | pf - > addr1 < < 8 | pf - > addr0 ;
float * val = ( float * ) & pf - > val [ 0 ] ;
bSetPointTableValueYC ( * val , adr ) ;
CP56Time t56 ( pf - > time ) ;
ycItem . stype = 2 ;
ycItem . dtime = t56 . GetTime ( ) ;
ycItem . sadr = adr ;
ycItem . fval = * val ;
ycItems . push_back ( ycItem ) ;
char buf [ 32 ] ;
t56 . GetTimeString ( buf , sizeof ( buf ) ) ;
vPrtLogMsg ( LOG_DEBUG , RET_OK , " type=%d SFP_%d: val:%-.4f OFlow: %d Valid: %d Blocked: %d time:%s " , header - > type , adr , * val , pf - > qds . ov , pf - > qds . iv , pf - > qds . bl , buf ) ;
pos + = sizeof ( SFP104_T ) ;
}
break ;
case 45 :
if ( cause = = 7 & & ! g_IecCtrl . is_yk_ack ) // 收到遥控返校
{
vYaoKongExe ( msgbuf , len ) ; // 遥控执行
g_IecCtrl . is_yk_ack = true ;
}
else if ( cause = = 7 & & g_IecCtrl . is_yk_ack )
{
vYaoKongUnexe ( msgbuf , len ) ; // 遥控撤销
g_IecCtrl . is_yk_ack = false ;
}
break ;
case 70 : //站端初始化结束
pos = sizeof ( ST_ASDU_HEADER ) ; // 跳过ASDU的头,size=6byte
idx = 0 ;
while ( pos < len )
{
memcpy ( & stObj [ idx ] . objaddr , msgbuf + pos , 3 ) ; // 信息对象地址, 3字节
stObj [ idx ] . objaddr = ntohi ( stObj [ idx ] . objaddr ) ; // 转高低位
pos + = 3 ;
if ( pos > = len ) break ;
stObj [ idx ] . objval = ( msgbuf [ pos ] & 0xff ) ; // 对象值, 0:电源合 1:电源分
idx + + ;
pos + + ;
}
vPrtLogMsg ( LOG_DEBUG , RET_OK , " End of Initialization " ) ;
break ;
case 100 : // 总召唤命令
if ( cause = = 7 ) // 激活确认
{
if ( g_TConfig . shouldParseBusiData ( ) ! = 0 )
{
ResetAllCachedDeviceData ( ) ;
}
vPrtLogMsg ( LOG_DEBUG , RET_OK , " Recv Activation Confirmation, %d. " , msgbuf [ 9 ] - 20 ) ;
}
else if ( cause = = 10 ) // 激活结束
{
g_IecCtrl . time_action = ts ; // time(NULL);
// SendMsgFormatS(sendno); // 总召唤结束发送S帧确认
if ( g_TConfig . shouldParseBusiData ( ) ! = 0 )
{
ResetAllCachedDeviceData ( ) ;
}
vPrtLogMsg ( LOG_DEBUG , RET_OK , " Recv Activation Termination, %d " , msgbuf [ 9 ] - 20 ) ;
}
else
vPrtLogMsg ( LOG_DEBUG , RET_OK , " Recv Command:%d ,Unknown. " , msgbuf [ 9 ] - 20 ) ;
break ;
default :
vPrtLogMsg ( LOG_WARNG , RET_OK , " Not Implemented!,type=%d " , header - > type ) ;
break ;
}
if ( ! ycItems . empty ( ) )
{
bSetPointTableValueYC ( ycItems ) ;
}
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 ) ) ;
g_Tcp . clear_tcp_buffer ( g_IecCtrl . sockid , MAX_SBUFF_TCP ) ;
g_Tcp . tcpCloseSocket ( g_IecCtrl . sockid ) ;
g_IecCtrl . isConnect = false ;
}
g_IecCtrl . time_action = - 1 ; // 总召间隔时间更新
vPrtLogHex ( LOG_PACK , g_IecCtrl . sockid , PRT_PACK_SEND , ( unsigned char * ) & stPack , iRet ) ;
}
return iRet ;
}
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 " ) ;
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 ( " \n FormatS " ) ;
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 ( " \n write=%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 ;
}
/***************************************************************************
* * 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: // 2: GIS负荷数据入库 iec_breaker_param
// dbSet_iec_breaker_param((ST_IEC_GISBREAK_TABLE*)stdbSet.pData);
// break;
// case 3: // 3: 负荷数据入库 iec_bydwork_param
// dbSet_iec_bydwork_param((ST_IEC_BYQWORK_TABLE*)stdbSet.pData);
// break;
// default:
// break;
// } // end switch
// free(stdbSet.pData);
// stdbSet.pData = NULL;
//}
// return NULL;
//}
/***************************************************************************
* * 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++)
// {
// // 2: GIS负荷数据入库 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 )
{
if ( ! g_IecCtrl . isConnect )
{
_SLEEP ( 1000 ) ;
continue ;
}
// 间隔1s
time_t timeOrigin = time ( NULL ) ;
// 定期总召
if ( ( g_IecCtrl . time_action ! = - 1 ) & & ( ( timeOrigin - g_IecCtrl . time_action ) > g_iec_conf . action_interval ) )
{
vPrtLogMsg ( LOG_DEBUG , RET_OK , " Send Activation " ) ;
SendMsgFormatIAction ( CMD_CTL_64H ) ; // 发送总召激活
}
_SLEEP ( 1000 ) ;
continue ;
while ( ( time ( NULL ) - timeOrigin ) < 1000 ) _SLEEP ( 1000 ) ;
if ( ! g_IecCtrl . isConnect ) // t0时间内连接未建立则重新连接并发送U启动帧激活数据传输
{
// time-out for reconnection.
g_IecCtrl . timer_t0 + + ; // t0++
if ( g_IecCtrl . timer_t0 > g_IecCtrl . t0 ) // TCP连接建立的超时时间(超时重新连接)
{
g_IecCtrl . timer_t0 = 0 ;
g_IecCtrl . isConnect = false ;
//if (master->OpenLink(master->RemoteHost, master->RemotePort) == EOK)
//SendMsgFormatU(CMD_STARTDT);
}
}
else
{
// maximun number of frames received before master send ACK. W
if ( ( g_IecCtrl . RxCounter - g_IecCtrl . LastAckRx ) > = g_IecCtrl . w * 2 )
// Send_S_Msg();
// time-out of waiting ACK to Sended APDU o TestFR
g_IecCtrl . timer_Confirm + + ;
// t1: RTU( 服务器) 端启动U格式测试过程后等待U格式测试应答的超时时间(超时处理:断开连接)
if ( g_IecCtrl . timer_Confirm > g_IecCtrl . timer_t1 )
{
if ( g_IecCtrl . TxCounter - g_IecCtrl . LastAckTx > 6 )
{
vPrtLogMsg ( LOG_WARNG , 0 , " Wait for U RESP timeout: TxCounter=%d LastAckTx=%d > 6, will close socket " , g_IecCtrl . TxCounter , g_IecCtrl . LastAckTx ) ;
g_Tcp . tcpCloseSocket ( g_IecCtrl . sockid ) ;
g_IecCtrl . isConnect = false ;
}
// g_IecCtrl.timer_Confirmflag = true;
}
// time-out for no data to send, send S-frame to ack data received. OK
g_IecCtrl . timer_t2 + + ;
// t2规定接收方在接收到I格式报文后, 若经过t2时间未再收到新的I格式报文,
// 则必须向发送方发送S格式帧对已经接收到的I格式报文进行认可, 显然t2必须小于t1。
if ( g_IecCtrl . timer_t2 > g_IecCtrl . t2 ) // (T2 < T1). S格式的超时时间
{
g_IecCtrl . timer_t2 = 0 ;
if ( g_IecCtrl . timer_S_Ackflag ) // 在收到I格式报文的时候置timer_S_Ack为0
SendMsgFormatS ( g_IecCtrl . usSendNo ) ;
g_IecCtrl . timer_S_Ackflag = true ;
}
// time-out for idle status, send test frame to check link state. OK
// t3规定调度端或子站RTU端每接收一帧 I帧、S帧或者U帧将重新触发计时器t3, 若在t3内未接收到任何报文, 将向对方发送测试链路帧
g_IecCtrl . timer_t3 + + ;
if ( g_IecCtrl . timer_t3 > g_IecCtrl . t3 ) // 没有实际的数据交换时, 任何一端启动U格式测试过程的最大间隔时间 (发送测试帧)
{
g_IecCtrl . timer_t3 = 0 ;
if ( g_IecCtrl . timer_U_Testflag ) // 接收到I S U帧都将timer_U_Test置为0
SendMsgFormatU ( CMD_TESTFR ) ;
g_IecCtrl . timer_U_Testflag = true ;
}
}
}
return NULL ;
}
/***************************************************************************
* * 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 ' ;
*/
}