Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c388bd04fe | |||
| c6ca57a204 | |||
| 2f584fda30 | |||
| 2f2e0d6430 | |||
| fc861024c3 | |||
| 3c98bf7eae | |||
| 073c98e89a | |||
| b1d8440e6a | |||
| b87da0f454 | |||
| 54c97ad103 | |||
| cf94a99cad | |||
| 1cde041e86 | |||
| fb55b76005 | |||
| 1b2dd863e9 | |||
| c78bc592a8 | |||
| 6f7ee762ec | |||
| 0acc58bbe1 | |||
| d1ed49412c | |||
| 748f8481bc | |||
| d5916f5559 | |||
| 50dd5c8a3e | |||
| 1bc32ae38c | |||
| fe8ba6fad9 | |||
| a2aa627b1e | |||
| 79676aa90d | |||
| 2e4a599200 | |||
| 320cf6d9ba | |||
| e2ee8546c7 | |||
| 78f95f2c96 | |||
| 2134a43e31 | |||
| 9d02a4b031 | |||
| 3b5b14f9ae |
175
arm_pro/pt61850netd_pqfe.pro
Normal file
175
arm_pro/pt61850netd_pqfe.pro
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
TARGET = pt61850netd_pqfe
|
||||||
|
DEPENDPATH += .
|
||||||
|
|
||||||
|
INCLUDEPATH += . \
|
||||||
|
./source \
|
||||||
|
./source/include \
|
||||||
|
./source/include/mmslite \
|
||||||
|
./source/include/pg_inst \
|
||||||
|
./source/include/curl \
|
||||||
|
./source/include/oss_sdk \
|
||||||
|
./source/include/rocketmq
|
||||||
|
|
||||||
|
QMAKE_ORIG_TARGET = $$(TARGET)
|
||||||
|
|
||||||
|
QT += core xml network
|
||||||
|
CONFIG += thread
|
||||||
|
|
||||||
|
DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||||
|
DEFINES += MMS_LITE LINUX=2 MOSI LEAN_T TP0_ENABLED
|
||||||
|
DEFINES += CLIENT _DEBUG _REENTRANT _GNU_SOURCE _LARGEFILE64_SOURCE
|
||||||
|
|
||||||
|
# debug/release flags
|
||||||
|
CONFIG(debug, debug|release) {
|
||||||
|
message("Building debug version with debug symbols")
|
||||||
|
QMAKE_CFLAGS_DEBUG += -g -O0
|
||||||
|
QMAKE_CXXFLAGS_DEBUG += -g -O0
|
||||||
|
CONFIG += force_debug_info
|
||||||
|
} else {
|
||||||
|
message("Building release version")
|
||||||
|
QMAKE_CFLAGS_RELEASE += -O2
|
||||||
|
QMAKE_CXXFLAGS_RELEASE += -O2
|
||||||
|
}
|
||||||
|
|
||||||
|
win32 {
|
||||||
|
DEFINES -= UNICODE
|
||||||
|
DEFINES += _AFXDLL
|
||||||
|
CONFIG += console
|
||||||
|
}
|
||||||
|
|
||||||
|
win32 {
|
||||||
|
# RC_FILE=pt61850netd_pqfe.rc
|
||||||
|
SOURCES += source/mms/event.c
|
||||||
|
INCLUDEPATH += ./source/include/apr
|
||||||
|
QMAKE_LFLAGS += /NODEFAULTLIB:libcmt.lib
|
||||||
|
LIBS += -L./lib -L./lib/mmslite -lws2_32
|
||||||
|
|
||||||
|
CONFIG(debug, debug|release) {
|
||||||
|
DEFINES += DEBUG_SISCO
|
||||||
|
MMS_LIB_SUFFIX = _ld.lib
|
||||||
|
QMAKE_POST_LINK = $$QMAKE_COPY debug\\*.exe ..\\..\\usr_bin\\jspqfe_home\\bin
|
||||||
|
} else {
|
||||||
|
MMS_LIB_SUFFIX = _n.lib
|
||||||
|
QMAKE_POST_LINK = $$QMAKE_COPY release\\*.exe ..\\..\\usr_bin\\jspqfe_home\\bin
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBS += ositcps$$MMS_LIB_SUFFIX \
|
||||||
|
mvl$$MMS_LIB_SUFFIX \
|
||||||
|
mmsle$$MMS_LIB_SUFFIX \
|
||||||
|
mmsl$$MMS_LIB_SUFFIX \
|
||||||
|
asn1$$MMS_LIB_SUFFIX \
|
||||||
|
mem$$MMS_LIB_SUFFIX \
|
||||||
|
meml$$MMS_LIB_SUFFIX \
|
||||||
|
slog$$MMS_LIB_SUFFIX \
|
||||||
|
utility$$MMS_LIB_SUFFIX \
|
||||||
|
ssec0$$MMS_LIB_SUFFIX
|
||||||
|
|
||||||
|
LIBS += -llibapr-1 -llibaprutil-1 -llibjclite
|
||||||
|
}
|
||||||
|
|
||||||
|
unix {
|
||||||
|
# 清掉旧标准
|
||||||
|
QMAKE_CXXFLAGS -= -std=gnu++98
|
||||||
|
QMAKE_CXXFLAGS -= -std=c++98
|
||||||
|
QMAKE_CXXFLAGS -= -std=gnu++11
|
||||||
|
QMAKE_CXXFLAGS -= -std=c++11
|
||||||
|
|
||||||
|
# 只保留一个
|
||||||
|
QMAKE_CXXFLAGS += -std=gnu++14
|
||||||
|
|
||||||
|
include(fe_common.pri)
|
||||||
|
SOURCES += source/mms/event2.c
|
||||||
|
INCLUDEPATH += ./source/include/apr-linux
|
||||||
|
|
||||||
|
LIBS += -L/FeProject/lib
|
||||||
|
# LIBS += -L/FeProject/lib/pgodbc
|
||||||
|
|
||||||
|
DEFINES += DEBUG_SISCO
|
||||||
|
VERSION = 1.0.0
|
||||||
|
|
||||||
|
# rpath
|
||||||
|
QMAKE_LFLAGS += -Wl,-rpath,/FeProject/lib \
|
||||||
|
-Wl,-rpath,/FeProject/lib/mmslite
|
||||||
|
|
||||||
|
LIBS += -lrt -lpthread
|
||||||
|
|
||||||
|
MMS_LIB_SUFFIX = _ld.a
|
||||||
|
LIBS += /FeProject/lib/mmslite/ositcps$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/mvl$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/mmsle$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/mmsl$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/asn1l$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/mem$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/slog$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/util$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/mmslite/ssec0$$MMS_LIB_SUFFIX \
|
||||||
|
/FeProject/lib/libcurl.so \
|
||||||
|
/FeProject/lib/libmxml4.so \
|
||||||
|
/FeProject/lib/librocketmq.so \
|
||||||
|
/FeProject/lib/libhttprun.so \
|
||||||
|
/FeProject/lib/liblog4cplus.so
|
||||||
|
|
||||||
|
LIBS += -lapr-1 -laprutil-1 -ljclite
|
||||||
|
LIBS += -lrdkafka++
|
||||||
|
LIBS += -lrdkafka
|
||||||
|
LIBS += -L/FeProject/lib -llog4cplus
|
||||||
|
LIBS += -L/root/JoyProject/3rdparty/boost_pic_aarch64/lib -Wl,--no-as-needed -lboost_iostreams -Wl,--as-needed
|
||||||
|
LIBS += -L/root/JoyProject/3rdparty/zlib_pic_aarch64/lib -lz
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# install
|
||||||
|
target.path = ../../bin
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
|
# Input
|
||||||
|
|
||||||
|
HEADERS += source/mms/db_interface.h \
|
||||||
|
source/include/otlv4.h \
|
||||||
|
source/mms/mmsclient.h \
|
||||||
|
source/mms/mmsop_en.h \
|
||||||
|
source/mms/rdb_client.h \
|
||||||
|
source/mms/ver_conf.h \
|
||||||
|
source/misc/SM4.h \
|
||||||
|
source/json/save2json.h \
|
||||||
|
source/json/mms_json_inter.h \
|
||||||
|
# source/json/rdkafka.h \
|
||||||
|
# source/json/rdkafkacpp.h \
|
||||||
|
# source/json/kafka_producer.h \
|
||||||
|
source/json/cjson.h \
|
||||||
|
source/rocketmq/SimpleProducer.h \
|
||||||
|
source/cfg_parse/custom_printf.h \
|
||||||
|
source/log4cplus/log4.h
|
||||||
|
|
||||||
|
SOURCES += source/mms/main.c \
|
||||||
|
source/mms/clntobj.c \
|
||||||
|
source/mms/logcfgx.c \
|
||||||
|
source/mms/mms_process.c \
|
||||||
|
source/mms/mmscli_rpt.c \
|
||||||
|
source/mms/mmsclient.c \
|
||||||
|
source/mms/mmslvar.c \
|
||||||
|
source/mms/mmsop_en.c \
|
||||||
|
source/mms/mvl_acse.c \
|
||||||
|
source/mms/mvlop_en.c \
|
||||||
|
source/mms/parse_xml.c \
|
||||||
|
source/mms/rdb_client.c \
|
||||||
|
source/mms/rdb_ext_utils.c \
|
||||||
|
source/mms/reject.c \
|
||||||
|
source/mms/mmscli_log.c \
|
||||||
|
source/misc/SM4.cpp \
|
||||||
|
source/misc/my_encrypt.cpp \
|
||||||
|
source/json/save2json.cpp \
|
||||||
|
source/cfg_parse/cfg_parser.cpp \
|
||||||
|
# source/json/kafka_producer.cpp \
|
||||||
|
source/json/create_json.cpp \
|
||||||
|
source/json/cjson.c \
|
||||||
|
source/cfg_parse/nacos.cpp \
|
||||||
|
source/cfg_parse/base64.cpp \
|
||||||
|
source/cfg_parse/SimpleProducer.cpp \
|
||||||
|
source/cfg_parse/log4.cpp \
|
||||||
|
# source/cfg_parse/oss_aliyun.cpp \
|
||||||
|
#source/cfg_parse/obs_huaweiyun.cpp \
|
||||||
|
# source/cfg_parse/datahub.cpp \
|
||||||
|
# source/cfg_parse/uds_huaweiyun.cpp
|
||||||
|
|
||||||
22
boot/feservice
Normal file
22
boot/feservice
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
'start')
|
||||||
|
$FEP_ENV/boot/start_fe.sh
|
||||||
|
;;
|
||||||
|
|
||||||
|
'stop')
|
||||||
|
$FEP_ENV/boot/stop_fe.sh
|
||||||
|
;;
|
||||||
|
|
||||||
|
'restart')
|
||||||
|
$FEP_ENV/boot/stop_fe.sh
|
||||||
|
$FEP_ENV/boot/start_fe.sh
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: feservice start|stop|restart"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
44
boot/ps_fe.sh
Normal file
44
boot/ps_fe.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# @file: $RCSfile: ps_fe.sh,v $
|
||||||
|
# @brief: $ϵͳӦ<CDB3><D3A6><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>̽ű<CCBD>
|
||||||
|
# @version: $Revision: 1.2 $
|
||||||
|
# @date: $Date: 2017/02/23 03:42:58 $
|
||||||
|
# @author: $Author: zhanchengguo $
|
||||||
|
# @state: $State: Exp $
|
||||||
|
# @latest: $Id: ps_fe.sh,v 1.2 2017/02/23 03:42:58 zhanchengguo Exp $
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
RUNTIME_CF_FILE="$FEP_ENV/etc/runtime.cf"
|
||||||
|
|
||||||
|
while read LINE ; do
|
||||||
|
if [ -n "$LINE" ] ; then
|
||||||
|
if [ ${LINE:0:1} != "#" ]; then
|
||||||
|
BINPATH=`echo $LINE | awk -F '^' '{printf $1}'`
|
||||||
|
BINPATH=`echo "$BINPATH" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BINPATH
|
||||||
|
BIN=`echo $LINE | awk -F '^' '{printf $2}'`
|
||||||
|
BIN=`echo "$BIN" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BIN
|
||||||
|
SPECIAL=`echo $LINE | awk -F '^' '{printf $4}'`
|
||||||
|
SPECIAL=`echo "$SPECIAL" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SPECIAL
|
||||||
|
|
||||||
|
SLEEPSEC=`echo $LINE | awk -F '^' '{printf $5}'`
|
||||||
|
SLEEPSEC=`echo "$SLEEPSEC" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SLEEPSEC
|
||||||
|
STARTFLAG=`echo $LINE | awk -F '^' '{printf $7}'`
|
||||||
|
STARTFLAG=`echo "$STARTFLAG" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $STARTFLAG
|
||||||
|
|
||||||
|
# if [ "`echo $STARTFLAG`" != "IGNORE_START" ]; then
|
||||||
|
CMD_STR=" ps -w | grep `echo "'"``echo $BIN``echo "'"` | grep -v 'grep'"
|
||||||
|
BIN2=`echo $BIN`
|
||||||
|
ps -ef | grep "$BIN2" | grep -v 'grep'
|
||||||
|
# fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < $RUNTIME_CF_FILE
|
||||||
|
|
||||||
|
echo ""
|
||||||
106
boot/start_fe.sh
Normal file
106
boot/start_fe.sh
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# @file: $RCSfile: start_fe.sh,v $
|
||||||
|
# @brief: $ϵͳӦ<CDB3><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||||
|
# @version: $Revision: 1.1 $
|
||||||
|
# @date: $Date: 2018/12/26 07:19:31 $
|
||||||
|
# @author: $Author: lizhongming $
|
||||||
|
# @state: $State: Exp $
|
||||||
|
# @latest: $Id: start_fe.sh,v 1.1 2018/12/26 07:19:31 lizhongming Exp $
|
||||||
|
|
||||||
|
QTDIR=/qt-4.8.4
|
||||||
|
export QTDIR
|
||||||
|
|
||||||
|
FEP_ENV=/FeProject
|
||||||
|
export FEP_ENV
|
||||||
|
|
||||||
|
PATH=$FEP_ENV/bin:$QTDIR/bin:$PATH
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=$FEP_ENV/lib:$FEP_ENV/lib3rd:$QTDIR/lib:$LD_LIBRARY_PATH
|
||||||
|
export LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
check_log_file()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ] ; then
|
||||||
|
FILE_SIZE=0
|
||||||
|
FILE_SIZE=`du $1 | awk '{print $1}'`
|
||||||
|
if [ $FILE_SIZE -ge 5120 ]
|
||||||
|
then
|
||||||
|
if [ -f "$1".3 ]; then
|
||||||
|
rm -f "$1".3
|
||||||
|
fi
|
||||||
|
if [ -f "$1".2 ]; then
|
||||||
|
mv "$1".2 "$1".3
|
||||||
|
fi
|
||||||
|
if [ -f "$1".1 ]; then
|
||||||
|
mv "$1".1 "$1".2
|
||||||
|
fi
|
||||||
|
mv "$1" "$1".1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGFILE="$FEP_ENV/dat/log/start_fe.log"
|
||||||
|
check_log_file $LOGFILE
|
||||||
|
|
||||||
|
|
||||||
|
echo "" ; echo ""
|
||||||
|
echo "******* `date "+%F %R:%S"` Start Processes *******"
|
||||||
|
echo "" >>"$LOGFILE"
|
||||||
|
echo "" >>"$LOGFILE"
|
||||||
|
echo "******* `date "+%F %R:%S"` Start Processes *******" >>"$LOGFILE"
|
||||||
|
#sysctl -w "kernel.core_pattern=/usr/local/sascore/%e.%p.%t.core" &> /dev/null
|
||||||
|
|
||||||
|
#ִ<>г<EFBFBD><D0B3><EFBFBD>·<EFBFBD><C2B7>^<5E><>ִ<EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>^<5E>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>^<5E>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
RUNTIME_CF_FILE="$FEP_ENV/etc/runtime.cf"
|
||||||
|
|
||||||
|
echo "Using config file name: $RUNTIME_CF_FILE"
|
||||||
|
echo "Using config file name: $RUNTIME_CF_FILE">>"$LOGFILE"
|
||||||
|
CURDIR=`pwd`
|
||||||
|
while read LINE ; do
|
||||||
|
if [ -n "$LINE" ] ; then
|
||||||
|
if [ ${LINE:0:1} != "#" ]; then
|
||||||
|
BINPATH=`echo $LINE | awk -F '^' '{printf $1}'`
|
||||||
|
BINPATH=`echo "$BINPATH" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BINPATH
|
||||||
|
BIN=`echo $LINE | awk -F '^' '{printf $2}'`
|
||||||
|
BIN=`echo "$BIN" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BIN
|
||||||
|
SPECIAL=`echo $LINE | awk -F '^' '{printf $4}'`
|
||||||
|
SPECIAL=`echo "$SPECIAL" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SPECIAL
|
||||||
|
|
||||||
|
SLEEPSEC=`echo $LINE | awk -F '^' '{printf $5}'`
|
||||||
|
SLEEPSEC=`echo "$SLEEPSEC" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SLEEPSEC
|
||||||
|
STARTFLAG=`echo $LINE | awk -F '^' '{printf $7}'`
|
||||||
|
STARTFLAG=`echo "$STARTFLAG" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $STARTFLAG
|
||||||
|
|
||||||
|
RESTARTFLAG=`echo $LINE | awk -F '^' '{printf $6}'`
|
||||||
|
RESTARTFLAG=`echo "$RESTARTFLAG" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
echo $RESTARTFLAG
|
||||||
|
|
||||||
|
if [ "$RESTARTFLAG" = "IGNORE_RESTART" ]; then
|
||||||
|
# echo "" ;
|
||||||
|
CMD_STR=" sleep `echo $SLEEPSEC` "
|
||||||
|
echo "$CMD_STR"
|
||||||
|
echo "$CMD_STR" >>"$LOGFILE"
|
||||||
|
$CMD_STR
|
||||||
|
|
||||||
|
CMD_STR=" `echo $BINPATH``echo $BIN` `echo $SPECIAL` "
|
||||||
|
echo "$CMD_STR"
|
||||||
|
echo "$CMD_STR" >>"$LOGFILE"
|
||||||
|
$CMD_STR &>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < $RUNTIME_CF_FILE
|
||||||
|
|
||||||
|
cd $CURDIR
|
||||||
|
|
||||||
|
DT=`date "+%F %R:%S.%N"`
|
||||||
|
echo "******* ${DT:0:23} Start Processes Succcessfully *******"
|
||||||
|
echo "******* ${DT:0:23} Start Processes Succcessfully *******" >>"$LOGFILE"
|
||||||
107
boot/stop_fe.sh
Normal file
107
boot/stop_fe.sh
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# @file: $RCSfile: stop_fe.sh,v $
|
||||||
|
# @brief: $ϵͳӦ<CDB3><D3A6>ֹͣ<CDA3><D6B9><EFBFBD>̽ű<CCBD>
|
||||||
|
# @version: $Revision: 1.5 $
|
||||||
|
# @date: $Date: 2017/02/28 08:40:43 $
|
||||||
|
# @author: $Author: zhanchengguo $
|
||||||
|
# @state: $State: Exp $
|
||||||
|
# @latest: $Id: stop_fe.sh,v 1.5 2017/02/28 08:40:43 zhanchengguo Exp $
|
||||||
|
|
||||||
|
check_log_file()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ] ; then
|
||||||
|
FILE_SIZE=0
|
||||||
|
FILE_SIZE=`du $1 | awk '{print $1}'`
|
||||||
|
if [ $FILE_SIZE -ge 5120 ]
|
||||||
|
then
|
||||||
|
if [ -f "$1".3 ]; then
|
||||||
|
rm -f "$1".3
|
||||||
|
fi
|
||||||
|
if [ -f "$1".2 ]; then
|
||||||
|
mv "$1".2 "$1".3
|
||||||
|
fi
|
||||||
|
if [ -f "$1".1 ]; then
|
||||||
|
mv "$1".1 "$1".2
|
||||||
|
fi
|
||||||
|
mv "$1" "$1".1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGFILE="/FeProject/dat/log/start_fe.log"
|
||||||
|
check_log_file $LOGFILE
|
||||||
|
|
||||||
|
echo "" ; echo ""
|
||||||
|
echo "****** `date "+%F %R:%S"` Stop Processes ******"
|
||||||
|
echo "" >>"$LOGFILE"
|
||||||
|
echo "" >>"$LOGFILE"
|
||||||
|
echo "****** `date "+%F %R:%S"` Stop Processes ******" >>"$LOGFILE"
|
||||||
|
|
||||||
|
RUNTIME_CF_FILE="/FeProject/etc/runtime.cf"
|
||||||
|
|
||||||
|
#cat $RUNTIME_CF_FILE |tac > /tmp/runtime.cf
|
||||||
|
sed '1!G;h;$!d' $RUNTIME_CF_FILE > /tmp/runtime.cf
|
||||||
|
|
||||||
|
echo "Using config file name: $RUNTIME_CF_FILE"
|
||||||
|
echo "Using config file name: $RUNTIME_CF_FILE">>"$LOGFILE"
|
||||||
|
|
||||||
|
while read LINE ; do
|
||||||
|
if [ -n "$LINE" ] ; then
|
||||||
|
if [ ${LINE:0:1} != "#" ]; then
|
||||||
|
BINPATH=`echo $LINE | awk -F '^' '{printf $1}'`
|
||||||
|
BINPATH=`echo "$BINPATH" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BINPATH
|
||||||
|
BIN=`echo $LINE | awk -F '^' '{printf $2}'`
|
||||||
|
BIN=`echo "$BIN" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $BIN
|
||||||
|
SPECIAL=`echo $LINE | awk -F '^' '{printf $4}'`
|
||||||
|
SPECIAL=`echo "$SPECIAL" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SPECIAL
|
||||||
|
|
||||||
|
SLEEPSEC=`echo $LINE | awk -F '^' '{printf $5}'`
|
||||||
|
SLEEPSEC=`echo "$SLEEPSEC" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $SLEEPSEC
|
||||||
|
STARTFLAG=`echo $LINE | awk -F '^' '{printf $7}'`
|
||||||
|
STARTFLAG=`echo "$STARTFLAG" | grep -o "[^ ]\+\( \+[^ ]\+\)*"`
|
||||||
|
# echo $STARTFLAG
|
||||||
|
|
||||||
|
if [ "`echo $STARTFLAG`" != "IGNORE_START" ]; then
|
||||||
|
# echo ""
|
||||||
|
# echo "" >>"$LOGFILE"
|
||||||
|
CMD_STR=" ps -w | grep `echo "'"``echo $BIN``echo "'"` | grep -v 'grep'"
|
||||||
|
BIN2=`echo $BIN`
|
||||||
|
BIN3=`echo $BIN |awk '{print$1}'`
|
||||||
|
# CMD_STR="killall `echo $BIN | awk '{print$1}'` 2>&1 "
|
||||||
|
PIDSTR=`ps -ef | grep "$BIN2" | grep -v 'grep'`
|
||||||
|
if [ -n "$PIDSTR" ] ; then
|
||||||
|
if [ "$BIN3" == "fe_main" ]; then
|
||||||
|
CMD_STR=" sleep 3 "
|
||||||
|
echo "$CMD_STR"
|
||||||
|
echo "$CMD_STR" >>"$LOGFILE"
|
||||||
|
$CMD_STR
|
||||||
|
fi
|
||||||
|
|
||||||
|
CMD_STR="kill -15 `echo $PIDSTR | awk '{print$2}'` "
|
||||||
|
echo " Kill process: \"$BIN\" with PID `echo $PIDSTR | awk '{print$2}'`"
|
||||||
|
echo " Kill process: \"$BIN\" with PID `echo $PIDSTR | awk '{print$2}'`" >>"$LOGFILE"
|
||||||
|
echo " Executing: $CMD_STR"
|
||||||
|
echo " Executing: $CMD_STR" >>"$LOGFILE"
|
||||||
|
CMD_RESULT=`$CMD_STR`
|
||||||
|
if [ -n "$CMD_RESULT" ] ; then
|
||||||
|
echo "$CMD_RESULT"
|
||||||
|
echo "$CMD_RESULT" >>"$LOGFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
echo " Process \"$BIN\" not running."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < /tmp/runtime.cf
|
||||||
|
|
||||||
|
DT=`date "+%F %R:%S.%N"`
|
||||||
|
echo "****** ${DT:0:23} Stop Processes Succcessfully ******"
|
||||||
|
echo "" >>"$LOGFILE"
|
||||||
|
echo "****** ${DT:0:23} Stop Processes Succcessfully ******" >>"$LOGFILE"
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../mms/db_interface.h"
|
#include "../mms/db_interface.h"
|
||||||
|
|
||||||
@@ -28,10 +29,14 @@
|
|||||||
#include "../rocketmq/DefaultMQPushConsumer.h"
|
#include "../rocketmq/DefaultMQPushConsumer.h"
|
||||||
#include "../rocketmq/ConsumeType.h"
|
#include "../rocketmq/ConsumeType.h"
|
||||||
|
|
||||||
|
#include "../rocketmq/MQMessageListener.h"
|
||||||
|
#include "../rocketmq/MQMessageExt.h"
|
||||||
|
#include "../rocketmq/SessionCredentials.h"
|
||||||
|
|
||||||
// 引入提供的消费者接口头文件
|
// 引入提供的消费者接口头文件
|
||||||
#include "../rocketmq/CPushConsumer.h"
|
//#include "../rocketmq/CPushConsumer.h"
|
||||||
#include "../rocketmq/CCommon.h"
|
//#include "../rocketmq/CCommon.h"
|
||||||
#include "../rocketmq/CMessageExt.h"
|
//#include "../rocketmq/CMessageExt.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <pthread.h> // 用于互斥锁(在 C++98 中没有 std::mutex)
|
#include <pthread.h> // 用于互斥锁(在 C++98 中没有 std::mutex)
|
||||||
#include <utility> // for std::pair
|
#include <utility> // for std::pair
|
||||||
@@ -40,20 +45,31 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
static std::once_flag g_consumer_once;
|
||||||
|
static std::once_flag g_producer_once;
|
||||||
|
|
||||||
extern std::string G_ROCKETMQ_PRODUCER;//rocketmq producer
|
extern std::string G_ROCKETMQ_PRODUCER;//rocketmq producer
|
||||||
extern std::string G_ROCKETMQ_IPPORT;//rocketmq ip+port
|
extern std::string G_ROCKETMQ_IPPORT;//rocketmq ip+port
|
||||||
extern std::string G_ROCKETMQ_TOPIC;//topie
|
|
||||||
extern std::string G_ROCKETMQ_TAG;//tag
|
extern std::string G_ROCKETMQ_TOPIC_TEST;//topie
|
||||||
extern std::string G_ROCKETMQ_KEY;//key
|
extern std::string G_ROCKETMQ_TAG_TEST;//tag
|
||||||
|
extern std::string G_ROCKETMQ_KEY_TEST;//key
|
||||||
|
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_LOG;
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_SET;
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_RC;
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_UD;
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_RT;
|
||||||
|
|
||||||
|
extern std::string G_MQCONSUMER_TOPIC_TEST;
|
||||||
|
|
||||||
extern std::string FRONT_INST;
|
extern std::string FRONT_INST;
|
||||||
|
extern bool DEBUGOPEN;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern std::string G_MQCONSUMER_TOPIC_SET; // C++ 中的全局变量声明
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -73,20 +89,40 @@ extern std::string G_MQCONSUMER_CHANNEL;
|
|||||||
class RocketMQConsumer;
|
class RocketMQConsumer;
|
||||||
|
|
||||||
// 全局映射:CPushConsumer* -> RocketMQConsumer*
|
// 全局映射:CPushConsumer* -> RocketMQConsumer*
|
||||||
std::map<CPushConsumer*, RocketMQConsumer*> g_consumerMap;//
|
//std::map<CPushConsumer*, RocketMQConsumer*> g_consumerMap;//
|
||||||
pthread_mutex_t g_consumerMapMutex = PTHREAD_MUTEX_INITIALIZER;
|
//pthread_mutex_t g_consumerMapMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
int64_t G_APP_START_MS = []() -> int64_t {
|
||||||
|
using namespace std::chrono;
|
||||||
|
return duration_cast<milliseconds>(
|
||||||
|
system_clock::now().time_since_epoch()
|
||||||
|
).count();
|
||||||
|
}();
|
||||||
|
|
||||||
|
int64_t G_START_SKEW_MS = 1000;
|
||||||
|
|
||||||
|
bool should_process_after_start(const rocketmq::MQMessageExt& msg)
|
||||||
|
{
|
||||||
|
const int64_t born_ts = static_cast<int64_t>(msg.getBornTimestamp());
|
||||||
|
return born_ts >= (G_APP_START_MS - G_START_SKEW_MS);
|
||||||
|
}
|
||||||
|
///////////////////////////////
|
||||||
|
class InternalListener;
|
||||||
|
|
||||||
class RocketMQConsumer {
|
class RocketMQConsumer {
|
||||||
public:
|
public:
|
||||||
// 构造函数:初始化消费者并启动
|
// 构造函数:初始化消费者并启动
|
||||||
RocketMQConsumer(const std::string& consumerName, const std::string& nameServer, const std::string& groupId);
|
RocketMQConsumer(const std::string& consumerName, const std::string& nameServer);
|
||||||
|
|
||||||
// 禁用拷贝和赋值
|
// 禁用拷贝和赋值
|
||||||
RocketMQConsumer(const RocketMQConsumer&) {}
|
RocketMQConsumer(const RocketMQConsumer&) = delete;
|
||||||
RocketMQConsumer& operator=(const RocketMQConsumer&) { return *this; }
|
RocketMQConsumer& operator=(const RocketMQConsumer&) = delete;
|
||||||
|
|
||||||
// 订阅主题和标签,并注册回调
|
// 订阅主题和标签,并注册回调
|
||||||
void subscribe(const std::string& topic, const std::string& tag, MessageCallBack callback);
|
void subscribe(const std::string& topic,
|
||||||
|
const std::string& tag,
|
||||||
|
MessageCallBack callback);
|
||||||
|
|
||||||
// 启动消费者
|
// 启动消费者
|
||||||
void start();
|
void start();
|
||||||
@@ -94,23 +130,47 @@ public:
|
|||||||
//修改消费模式
|
//修改消费模式
|
||||||
void setConsumerMessageModel(const std::string& topic);
|
void setConsumerMessageModel(const std::string& topic);
|
||||||
|
|
||||||
|
rocketmq::ConsumeStatus handleMessage(const rocketmq::MQMessageExt& msg);
|
||||||
|
|
||||||
// 析构函数:关闭并销毁消费者
|
// 析构函数:关闭并销毁消费者
|
||||||
~RocketMQConsumer();
|
~RocketMQConsumer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPushConsumer* consumer_; // C 接口消费者指针
|
//CPushConsumer* consumer_; // C 接口消费者指针
|
||||||
//MessageCallBack messageCallback_; // 函数指针用于回调
|
//MessageCallBack messageCallback_; // 函数指针用于回调
|
||||||
|
rocketmq::DefaultMQPushConsumer consumer_;
|
||||||
|
InternalListener* listener_;
|
||||||
|
|
||||||
std::map<std::pair<std::string, std::string>, MessageCallBack> callbacks_; // 订阅到回调的映射
|
std::map<std::pair<std::string, std::string>, MessageCallBack> callbacks_; // 订阅到回调的映射
|
||||||
|
|
||||||
// 静态消息处理回调
|
/*// 静态消息处理回调
|
||||||
static int messageHandler(CPushConsumer* consumer, CMessageExt* msg);
|
static int messageHandler(CPushConsumer* consumer, CMessageExt* msg);
|
||||||
|
|
||||||
// 实例消息处理函数
|
// 实例消息处理函数
|
||||||
int handleMessage(CMessageExt* msg);
|
int handleMessage(CMessageExt* msg);*/
|
||||||
};
|
|
||||||
|
|
||||||
// 构造函数实现
|
};
|
||||||
RocketMQConsumer::RocketMQConsumer(const std::string& consumerName, const std::string& nameServer, const std::string& groupId)
|
class InternalListener : public rocketmq::MessageListenerConcurrently {
|
||||||
|
public:
|
||||||
|
explicit InternalListener(RocketMQConsumer* owner)
|
||||||
|
: owner_(owner) {}
|
||||||
|
|
||||||
|
rocketmq::ConsumeStatus consumeMessage(
|
||||||
|
const std::vector<rocketmq::MQMessageExt>& msgs) override
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < msgs.size(); ++i) {
|
||||||
|
rocketmq::ConsumeStatus ret = owner_->handleMessage(msgs[i]);
|
||||||
|
if (ret != rocketmq::CONSUME_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rocketmq::CONSUME_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RocketMQConsumer* owner_;
|
||||||
|
};
|
||||||
|
// 构造函数实现C
|
||||||
|
/*RocketMQConsumer::RocketMQConsumer(const std::string& consumerName, const std::string& nameServer, const std::string& groupId)
|
||||||
: consumer_(NULL)//, messageCallback_(NULL)
|
: consumer_(NULL)//, messageCallback_(NULL)
|
||||||
{
|
{
|
||||||
// 创建消费者
|
// 创建消费者
|
||||||
@@ -157,35 +217,58 @@ RocketMQConsumer::RocketMQConsumer(const std::string& consumerName, const std::s
|
|||||||
pthread_mutex_unlock(&g_consumerMapMutex);
|
pthread_mutex_unlock(&g_consumerMapMutex);
|
||||||
|
|
||||||
std::cout << "RocketMQ Consumer initialized and started." << std::endl;
|
std::cout << "RocketMQ Consumer initialized and started." << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//构造函数实现C++
|
||||||
|
RocketMQConsumer::RocketMQConsumer(const std::string& consumerGroup,
|
||||||
|
const std::string& nameServer)
|
||||||
|
: consumer_(consumerGroup),
|
||||||
|
listener_(NULL)
|
||||||
|
{
|
||||||
|
consumer_.setNamesrvAddr(nameServer);
|
||||||
|
|
||||||
|
consumer_.setSessionCredentials(
|
||||||
|
G_MQCONSUMER_ACCESSKEY,
|
||||||
|
G_MQCONSUMER_SECRETKEY,
|
||||||
|
G_MQCONSUMER_CHANNEL
|
||||||
|
);
|
||||||
|
|
||||||
|
// 限制消费线程池,防止 ConsumeTP 爆炸
|
||||||
|
consumer_.setConsumeThreadCount(4);
|
||||||
|
|
||||||
|
listener_ = new InternalListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动消费者
|
// 启动消费者
|
||||||
void RocketMQConsumer::start()
|
void RocketMQConsumer::start()
|
||||||
{
|
{
|
||||||
if (StartPushConsumer(consumer_) != 0) {
|
static bool started = false;
|
||||||
pthread_mutex_lock(&g_consumerMapMutex);
|
if (started) {
|
||||||
g_consumerMap.erase(consumer_);
|
std::cout << "Consumer already started" << std::endl;
|
||||||
pthread_mutex_unlock(&g_consumerMapMutex);
|
return;
|
||||||
DestroyPushConsumer(consumer_);
|
|
||||||
throw std::runtime_error("Failed to start push consumer.");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
std::cout << "RocketMQ Consumer started." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consumer_.registerMessageListener(listener_);
|
||||||
|
consumer_.start();
|
||||||
|
|
||||||
|
started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RocketMQConsumer::subscribe(const std::string& topic, const std::string& tag, MessageCallBack callback)
|
void RocketMQConsumer::subscribe(const std::string& topic, const std::string& tag, MessageCallBack callback)
|
||||||
{
|
{
|
||||||
if (Subscribe(consumer_, topic.c_str(), tag.c_str()) != 0) {
|
/*if (Subscribe(consumer_, topic.c_str(), tag.c_str()) != 0) {
|
||||||
throw std::runtime_error("Failed to subscribe to topic/tag.");
|
throw std::runtime_error("Failed to subscribe to topic/tag.");
|
||||||
}
|
}*/
|
||||||
|
consumer_.subscribe(topic, tag);
|
||||||
|
|
||||||
|
//调试用
|
||||||
std::cout << "Subscribed to topic: " << topic << ", tag: " << tag << std::endl;
|
std::cout << "Subscribed to topic: " << topic << ", tag: " << tag << std::endl;
|
||||||
|
|
||||||
// 使用 std::pair 作为键
|
// 使用 std::pair 作为键
|
||||||
std::pair<std::string, std::string> key(topic, tag);
|
std::pair<std::string, std::string> mapKey(topic, tag);
|
||||||
callbacks_[key] = callback;
|
callbacks_[mapKey] = callback;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// 静态消息处理回调实现
|
// 静态消息处理回调实现
|
||||||
int RocketMQConsumer::messageHandler(CPushConsumer* consumer, CMessageExt* msg)
|
int RocketMQConsumer::messageHandler(CPushConsumer* consumer, CMessageExt* msg)
|
||||||
{
|
{
|
||||||
@@ -206,68 +289,66 @@ int RocketMQConsumer::messageHandler(CPushConsumer* consumer, CMessageExt* msg)
|
|||||||
return instance->handleMessage(msg);
|
return instance->handleMessage(msg);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Consumer instance not found for callback." << std::endl;
|
std::cerr << "Consumer instance not found for callback." << std::endl;
|
||||||
return E_RECONSUME_LATER; // 默认返回重试状态
|
//return E_RECONSUME_LATER; // 默认返回重试状态
|
||||||
|
return rocketmq::RECONSUME_LATER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
int RocketMQConsumer::handleMessage(CMessageExt* msg)
|
/*int RocketMQConsumer::handleMessage(CMessageExt* msg)
|
||||||
{
|
{
|
||||||
// 检查 msg 和 consumer_ 是否为 NULL
|
// 检查 msg 和 consumer_ 是否为 NULL
|
||||||
if (!msg || !consumer_) {
|
if (!msg || !consumer_) {
|
||||||
std::cerr << "Received null message or consumer." << std::endl;
|
std::cerr << "Received null message or consumer." << std::endl;
|
||||||
return E_RECONSUME_LATER;
|
//return E_RECONSUME_LATER;
|
||||||
}
|
return rocketmq::RECONSUME_LATER;
|
||||||
|
}*/
|
||||||
|
|
||||||
// 获取消息的主题和标签
|
// 获取消息的主题和标签
|
||||||
std::string topic = GetMessageTopic(msg); // 假设存在此函数
|
//std::string topic = GetMessageTopic(msg); // 假设存在此函数
|
||||||
std::string tag = GetMessageTags(msg); // 假设存在此函数
|
//std::string tag = GetMessageTags(msg); // 假设存在此函数
|
||||||
|
|
||||||
// 打印调试信息
|
rocketmq::ConsumeStatus RocketMQConsumer::handleMessage( const rocketmq::MQMessageExt& msg) {
|
||||||
std::cout << "Handling message for topic: " << topic << ", tag: " << tag << std::endl;
|
std::string tag = msg.getTags();
|
||||||
|
std::string topic = msg.getTopic();
|
||||||
// 使用 std::pair 作为键
|
// 打印调试信息
|
||||||
std::pair<std::string, std::string> key(topic, tag);
|
std::cout << "Handling message for topic: " << topic << ", tag: " << tag << std::endl;
|
||||||
|
// 使用 std::pair 作为键
|
||||||
// 查找对应的回调函数
|
std::pair<std::string, std::string> key(topic, tag);
|
||||||
std::map<std::pair<std::string, std::string>, MessageCallBack>::iterator it = callbacks_.find(key);
|
// 查找对应的回调函数
|
||||||
if (it != callbacks_.end()) {
|
std::map<std::pair<std::string, std::string>, MessageCallBack>::iterator it = callbacks_.find(key);
|
||||||
// 调用对应的回调函数
|
if (it != callbacks_.end())
|
||||||
|
{ // 调用对应的回调函数
|
||||||
//调试
|
//调试
|
||||||
std::cout << "callback Handling message " <<std::endl;
|
std::cout << "callback Handling message " <<std::endl;
|
||||||
|
//return it->second(consumer_, msg);
|
||||||
return it->second(consumer_, msg);
|
return it->second(msg);
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
//调试
|
||||||
//调试
|
std::cout << "there is no callback " <<std::endl;
|
||||||
std::cout << "there is no callback " <<std::endl;
|
// 如果没有找到对应的回调,执行默认处理
|
||||||
|
//const char* body = GetMessageBody(msg);
|
||||||
// 如果没有找到对应的回调,执行默认处理
|
//const char* msgKey = GetMessageKeys(msg);
|
||||||
const char* body = GetMessageBody(msg);
|
std::string body = msg.getBody();
|
||||||
const char* msgKey = GetMessageKeys(msg);
|
std::string msgKey = msg.getKeys();
|
||||||
|
if (!body.empty()) {
|
||||||
if (body) {
|
std::cout << "Received message body: " << body << std::endl;
|
||||||
std::cout << "Received message body: " << body << std::endl;
|
} else {
|
||||||
} else {
|
std::cout << "Received message with empty body." << std::endl;
|
||||||
std::cout << "Received message with empty body." << std::endl;
|
} if (!msgKey.empty()) {
|
||||||
}
|
std::cout << "Message Key: " << msgKey << std::endl;
|
||||||
|
} else {
|
||||||
if (msgKey) {
|
std::cout << "Message Key: N/A" << std::endl;
|
||||||
std::cout << "Message Key: " << msgKey << std::endl;
|
} //return E_CONSUME_SUCCESS;
|
||||||
} else {
|
return rocketmq::CONSUME_SUCCESS;
|
||||||
std::cout << "Message Key: N/A" << std::endl;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return E_CONSUME_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 析构函数实现
|
// 析构函数实现
|
||||||
RocketMQConsumer::~RocketMQConsumer()
|
RocketMQConsumer::~RocketMQConsumer()
|
||||||
{
|
{
|
||||||
if (consumer_) {
|
/*if (consumer_) {
|
||||||
// 关闭消费者
|
// 关闭消费者
|
||||||
ShutdownPushConsumer(consumer_);
|
ShutdownPushConsumer(consumer_);
|
||||||
|
|
||||||
@@ -281,7 +362,18 @@ RocketMQConsumer::~RocketMQConsumer()
|
|||||||
consumer_ = NULL;
|
consumer_ = NULL;
|
||||||
|
|
||||||
std::cout << "RocketMQ Consumer shutdown and destroyed." << std::endl;
|
std::cout << "RocketMQ Consumer shutdown and destroyed." << std::endl;
|
||||||
|
}*/
|
||||||
|
try {
|
||||||
|
consumer_.shutdown();
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sleep(1); // 等内部线程退出
|
||||||
|
|
||||||
|
delete listener_;
|
||||||
|
listener_ = NULL;
|
||||||
|
|
||||||
|
std::cout << "RocketMQ Consumer shutdown and destroyed." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在 RocketMQConsumer 类中新增函数用来设置消费模式
|
// 在 RocketMQConsumer 类中新增函数用来设置消费模式
|
||||||
@@ -296,11 +388,13 @@ void RocketMQConsumer::setConsumerMessageModel(const std::string& topic)
|
|||||||
}
|
}
|
||||||
} else*/ {
|
} else*/ {
|
||||||
// 默认设置为广播消费模式
|
// 默认设置为广播消费模式
|
||||||
if (SetPushConsumerMessageModel(consumer_, BROADCASTING) != 0) {
|
/*if (SetPushConsumerMessageModel(consumer_, BROADCASTING) != 0) {
|
||||||
std::cout << "Error setting message model to BROADCASTING for topic: " << topic << std::endl;
|
std::cout << "Error setting message model to BROADCASTING for topic: " << topic << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Set consumer to BROADCASTING for topic: " << topic << std::endl;
|
std::cout << "Set consumer to BROADCASTING for topic: " << topic << std::endl;
|
||||||
}
|
}*/
|
||||||
|
consumer_.setMessageModel(rocketmq::BROADCASTING);
|
||||||
|
std::cout << "Set consumer to BROADCASTING for topic: " << topic << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,11 +410,12 @@ void InitializeConsumer(
|
|||||||
if (g_consumer == NULL) {
|
if (g_consumer == NULL) {
|
||||||
std::cout << "create new consumer!" << std::endl;
|
std::cout << "create new consumer!" << std::endl;
|
||||||
try {
|
try {
|
||||||
g_consumer = new RocketMQConsumer(consumerName, nameServer,consumerName);//用消费名作为消费组,不同进程(不同的消费者)同时消费topic的同一条消息
|
//g_consumer = new RocketMQConsumer(consumerName, nameServer,consumerName);//用消费名作为消费组,不同进程(不同的消费者)同时消费topic的同一条消息
|
||||||
|
g_consumer = new RocketMQConsumer(consumerName, nameServer);
|
||||||
|
|
||||||
for (size_t i = 0; i < subscriptions.size(); ++i) {
|
for (size_t i = 0; i < subscriptions.size(); ++i) {
|
||||||
g_consumer->setConsumerMessageModel(subscriptions[i].topic);//初始化时根据topic设置消费模式
|
g_consumer->setConsumerMessageModel(subscriptions[i].topic);//初始化时根据topic设置消费模式
|
||||||
g_consumer->subscribe(subscriptions[i].topic, subscriptions[i].tag, subscriptions[i].callback);
|
g_consumer->subscribe(subscriptions[i].topic, subscriptions[i].tag,subscriptions[i].callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_consumer->start();
|
g_consumer->start();
|
||||||
@@ -348,16 +443,13 @@ void rocketmq_consumer_receive(
|
|||||||
const std::string& nameServer,
|
const std::string& nameServer,
|
||||||
const std::vector<Subscription>& subscriptions) // 接收多个订阅
|
const std::vector<Subscription>& subscriptions) // 接收多个订阅
|
||||||
{
|
{
|
||||||
if (g_consumer == NULL) {
|
std::call_once(g_consumer_once, [&](){
|
||||||
try {
|
try {
|
||||||
//InitializeConsumer(consumerName, nameServer, topic, tag, callback);//初始化后,mq库内部来完成消息的获取
|
InitializeConsumer(consumerName, nameServer, subscriptions);
|
||||||
InitializeConsumer(consumerName, nameServer, subscriptions); // 初始化后,MQ库内部开始获取消息
|
} catch (...) {
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
std::cerr << "Cannot consume message because consumer initialization failed." << std::endl;
|
std::cerr << "Cannot consume message because consumer initialization failed." << std::endl;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -367,7 +459,7 @@ void rocketmq_consumer_receive(
|
|||||||
static int currentQueueId = 0;
|
static int currentQueueId = 0;
|
||||||
|
|
||||||
// 队列选择器回调函数:轮询选择队列 ID
|
// 队列选择器回调函数:轮询选择队列 ID
|
||||||
int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
|
/*int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
|
||||||
if (queueNum == 0) {
|
if (queueNum == 0) {
|
||||||
throw std::runtime_error("No available queues");
|
throw std::runtime_error("No available queues");
|
||||||
}
|
}
|
||||||
@@ -377,27 +469,60 @@ int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
|
|||||||
currentQueueId = 0;
|
currentQueueId = 0;
|
||||||
}
|
}
|
||||||
return queueId;
|
return queueId;
|
||||||
|
}*/
|
||||||
|
int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
|
||||||
|
static std::atomic<int> currentQueueId(0);
|
||||||
|
|
||||||
|
if (queueNum <= 0) {
|
||||||
|
std::cout << "[MQ][SELECTOR_FAIL] queueNum=" << queueNum << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = currentQueueId.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
int queueId = id % queueNum;
|
||||||
|
|
||||||
|
std::cout << "[MQ][SELECTOR] queueNum=" << queueNum
|
||||||
|
<< ", current=" << id
|
||||||
|
<< ", selected=" << queueId
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
return queueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 封装生产者的类
|
// 封装生产者的类
|
||||||
class RocketMQProducer {
|
class RocketMQProducer {
|
||||||
public:
|
public:
|
||||||
RocketMQProducer(const std::string& producerName, const std::string& nameServer)
|
RocketMQProducer(const std::string& producerName, const std::string& nameServer)
|
||||||
: producer_(NULL)
|
: producer_(producerName)
|
||||||
{
|
{
|
||||||
// 创建生产者
|
// 创建生产者
|
||||||
producer_ = CreateProducer(producerName.c_str());
|
/*producer_ = CreateProducer(producerName.c_str());
|
||||||
if (producer_ == NULL) {
|
if (producer_ == NULL) {
|
||||||
throw std::runtime_error("Failed to create producer.");
|
throw std::runtime_error("Failed to create producer.");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
// 设置日志
|
||||||
|
producer_.setLogLevel(rocketmq::eLOG_LEVEL_ERROR);
|
||||||
|
producer_.setLogFileSizeAndNum(5, 50);
|
||||||
|
|
||||||
// 设置 nameserver 地址
|
// 设置 nameserver 地址
|
||||||
SetProducerNameServerAddress(producer_, nameServer.c_str());
|
//SetProducerNameServerAddress(producer_, nameServer.c_str());
|
||||||
|
producer_.setNamesrvAddr(nameServer);
|
||||||
|
|
||||||
SetProducerSessionCredentials(producer_, G_MQCONSUMER_ACCESSKEY.c_str(),G_MQCONSUMER_SECRETKEY.c_str(), "");
|
//lnk20260417设置数据上送消息体最大值,默认4M,调整为1M,避免过大消息导致发送失败
|
||||||
|
//SetProducerMaxMessageSize(producer_, 1024 * 1024); // 1MB
|
||||||
|
producer_.setMaxMessageSize(1024 * 1024);
|
||||||
|
|
||||||
|
//SetProducerSessionCredentials(producer_, G_MQCONSUMER_ACCESSKEY.c_str(),G_MQCONSUMER_SECRETKEY.c_str(), "");
|
||||||
|
producer_.setSessionCredentials(
|
||||||
|
G_MQCONSUMER_ACCESSKEY,
|
||||||
|
G_MQCONSUMER_SECRETKEY,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
// 启动生产者
|
// 启动生产者
|
||||||
StartProducer(producer_);
|
//StartProducer(producer_);
|
||||||
|
producer_.start();
|
||||||
|
|
||||||
std::cout << "rocketmq_Producer initialized and started." << std::endl;
|
std::cout << "rocketmq_Producer initialized and started." << std::endl;
|
||||||
}
|
}
|
||||||
@@ -406,7 +531,7 @@ public:
|
|||||||
RocketMQProducer(const RocketMQProducer&) = delete;
|
RocketMQProducer(const RocketMQProducer&) = delete;
|
||||||
RocketMQProducer& operator=(const RocketMQProducer&) = delete;
|
RocketMQProducer& operator=(const RocketMQProducer&) = delete;
|
||||||
|
|
||||||
void printSendResult(const CSendResult& result) {
|
/*void printSendResult(const CSendResult& result) {
|
||||||
std::cout << "SendResult:" << std::endl;
|
std::cout << "SendResult:" << std::endl;
|
||||||
std::cout << " Status: ";
|
std::cout << " Status: ";
|
||||||
switch (result.sendStatus) {
|
switch (result.sendStatus) {
|
||||||
@@ -430,10 +555,68 @@ public:
|
|||||||
|
|
||||||
std::cout << " MsgID : " << result.msgId << std::endl;
|
std::cout << " MsgID : " << result.msgId << std::endl;
|
||||||
std::cout << " Offset: " << result.offset << std::endl;
|
std::cout << " Offset: " << result.offset << std::endl;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
void sendMessage(const char* strbody, const char* topic, const std::string& tags, const std::string& keys) {
|
/* void sendMessage(const char* strbody, const char* topic, const std::string& tags, const std::string& keys) {
|
||||||
|
|
||||||
|
if (DEBUGOPEN) {
|
||||||
|
std::cout << "sendMessage called with topic: " << (topic ? topic : "NULL")
|
||||||
|
<< ", tags: " << tags
|
||||||
|
<< ", keys: " << keys
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (strbody) {
|
||||||
|
// ===== 1️⃣ 真实长度 vs strlen =====
|
||||||
|
std::string body_str(strbody);
|
||||||
|
|
||||||
|
std::cout << "[MQ][LEN_CHECK]"
|
||||||
|
<< " strlen=" << strlen(strbody)
|
||||||
|
<< ", std::string.size=" << body_str.size()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
// ===== 2️⃣ 检测是否包含 \0 =====
|
||||||
|
bool has_null = false;
|
||||||
|
for (size_t i = 0; i < body_str.size(); i++) {
|
||||||
|
if (body_str[i] == '\0') {
|
||||||
|
has_null = true;
|
||||||
|
std::cout << "[MQ][FOUND_NULL] index=" << i << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "[MQ][HAS_NULL] " << (has_null ? "YES" : "NO") << std::endl;
|
||||||
|
|
||||||
|
// ===== 3️⃣ 打印头部(可读)=====
|
||||||
|
size_t len = strlen(strbody);
|
||||||
|
size_t n = std::min((size_t)200, len);
|
||||||
|
|
||||||
|
std::cout << "[MQ][BODY_HEAD] "
|
||||||
|
<< std::string(strbody, n)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::cout << "[MQ][BODY_TAIL] "
|
||||||
|
<< std::string(strbody + (len - n), n)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
// ===== 4️⃣ 十六进制打印前100字节 =====
|
||||||
|
std::cout << "[MQ][HEX_HEAD] ";
|
||||||
|
for (size_t i = 0; i < std::min((size_t)100, body_str.size()); i++) {
|
||||||
|
printf("%02X ", (unsigned char)body_str[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// ===== 5️⃣ 十六进制打印尾部100字节 =====
|
||||||
|
std::cout << "[MQ][HEX_TAIL] ";
|
||||||
|
size_t start = (body_str.size() > 100) ? body_str.size() - 100 : 0;
|
||||||
|
for (size_t i = start; i < body_str.size(); i++) {
|
||||||
|
printf("%02X ", (unsigned char)body_str[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
} else {
|
||||||
|
std::cout << "[MQ][ERROR] strbody is NULL" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSendResult result;
|
CSendResult result;
|
||||||
CMessage* msg = NULL;
|
CMessage* msg = NULL;
|
||||||
|
|
||||||
@@ -458,11 +641,67 @@ public:
|
|||||||
RoundRobinSelector, // 队列选择器回调函数
|
RoundRobinSelector, // 队列选择器回调函数
|
||||||
&queueNum // 传递给选择器的额外参数(队列数量)
|
&queueNum // 传递给选择器的额外参数(队列数量)
|
||||||
);
|
);
|
||||||
|
/////////////////////////////////替换接口,性能较低但不影响
|
||||||
|
/*CSendResult result;
|
||||||
|
memset(&result, 0, sizeof(result));
|
||||||
|
|
||||||
|
int sendResult = SendMessageOrderly(
|
||||||
|
producer_,
|
||||||
|
msg,
|
||||||
|
RoundRobinSelector,
|
||||||
|
&queueNum,
|
||||||
|
0, // autoRetryTimes
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout << "[MQ][ORDERLY_RESULT]"
|
||||||
|
<< " ret=" << sendResult
|
||||||
|
<< ", sendStatus=" << (int)result.sendStatus
|
||||||
|
<< ", msgId=" << result.msgId
|
||||||
|
<< ", offset=" << result.offset
|
||||||
|
<< ", topic=" << (topic ? topic : "")
|
||||||
|
<< ", body_len=" << (strbody ? strlen(strbody) : 0)
|
||||||
|
<< std::endl;*/
|
||||||
|
/////////////////////////////////替换接口,性能较低但不影响
|
||||||
|
// 发送消息:临时改成同步发送,绕过 orderly / selector,便于定位问题
|
||||||
|
/*CSendResult result;
|
||||||
|
memset(&result, 0, sizeof(result));
|
||||||
|
|
||||||
|
int sendResult = SendMessageSync(
|
||||||
|
producer_,
|
||||||
|
msg,
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout << "[MQ][SYNC_RESULT]"
|
||||||
|
<< " ret=" << sendResult
|
||||||
|
<< ", sendStatus=" << (int)result.sendStatus
|
||||||
|
<< ", msgId=" << result.msgId
|
||||||
|
<< ", offset=" << result.offset
|
||||||
|
<< ", topic=" << (topic ? topic : "")
|
||||||
|
<< ", body_len=" << (strbody ? strlen(strbody) : 0)
|
||||||
|
<< std::endl;*/
|
||||||
|
// 发送消息:临时改成同步发送,绕过 orderly / selector,便于定位问题
|
||||||
|
|
||||||
if (sendResult == 0) { // 假设返回 0 表示成功
|
/*if (sendResult == 0) { // 假设返回 0 表示成功
|
||||||
std::cout << "Message sent successfully.topic:" << topic <<std::endl;
|
std::cout << "[MQ][SEND_OK]"
|
||||||
|
<< " topic=" << (topic ? topic : "")
|
||||||
|
<< ", tags=" << tags
|
||||||
|
<< ", keys=" << keys
|
||||||
|
<< ", body_len=" << (strbody ? strlen(strbody) : 0)
|
||||||
|
<< std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Failed to send message." << std::endl;
|
|
||||||
|
std::cout << "[MQ][SEND_FAIL]"
|
||||||
|
<< " ret=" << sendResult
|
||||||
|
<< ", topic=" << (topic ? topic : "")
|
||||||
|
<< ", tags=" << tags
|
||||||
|
<< ", keys=" << keys
|
||||||
|
<< ", body_len=" << (strbody ? strlen(strbody) : 0)
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << "[MQ][BODY_HEAD] " << std::string(strbody, std::min((size_t)200, strlen(strbody))) << std::endl;
|
||||||
|
std::cout << "[MQ][BODY_TAIL] " << std::string(strbody + std::max((size_t)0, strlen(strbody) - std::min((size_t)200, strlen(strbody)))) << std::endl;
|
||||||
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_MQ,"【ERROR】前置的%s%d号进程 mq发送失败,请检查mq配置", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 销毁消息
|
// 销毁消息
|
||||||
@@ -489,20 +728,97 @@ public:
|
|||||||
DestroyMessage(msg);
|
DestroyMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
void sendMessage(const std::string& body,
|
||||||
|
const std::string& topic,
|
||||||
|
const std::string& tags,
|
||||||
|
const std::string& keys)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (DEBUGOPEN) {
|
||||||
|
std::cout << "sendMessage called with topic: " << topic
|
||||||
|
<< ", tags: " << tags
|
||||||
|
<< ", keys: " << keys
|
||||||
|
<< ", body_len=" << body.size()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
size_t n = std::min((size_t)200, body.size());
|
||||||
|
|
||||||
|
std::cout << "[MQ][BODY_HEAD] "
|
||||||
|
<< body.substr(0, n)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (body.size() > n) {
|
||||||
|
std::cout << "[MQ][BODY_TAIL] "
|
||||||
|
<< body.substr(body.size() - n, n)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[MQ][HEX_HEAD] ";
|
||||||
|
for (size_t i = 0; i < std::min((size_t)100, body.size()); ++i) {
|
||||||
|
printf("%02X ", (unsigned char)body[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
rocketmq::MQMessage msg(topic, tags, keys, body);
|
||||||
|
|
||||||
|
rocketmq::SendResult result = producer_.send(msg);
|
||||||
|
|
||||||
|
std::cout << "[MQ][SEND_OK]"
|
||||||
|
<< " topic=" << topic
|
||||||
|
<< ", tags=" << tags
|
||||||
|
<< ", keys=" << keys
|
||||||
|
<< ", msgId=" << result.getMsgId()
|
||||||
|
<< ", status=" << result.getSendStatus()
|
||||||
|
<< ", body_len=" << body.size()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
catch (const rocketmq::MQClientException& e) {
|
||||||
|
std::cerr << "[MQ][SEND_FAIL] MQClientException: "
|
||||||
|
<< e.what() << std::endl;
|
||||||
|
|
||||||
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_MQ,
|
||||||
|
"【ERROR】前置的%s%d号进程 mq发送失败,mq客户端错误,请检查mq配置",
|
||||||
|
get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
std::cerr << "[MQ][SEND_FAIL] exception: "
|
||||||
|
<< e.what() << std::endl;
|
||||||
|
|
||||||
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_MQ,
|
||||||
|
"【ERROR】前置的%s%d号进程 mq发送失败,mq发送错误,发送请检查mq配置",
|
||||||
|
get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
std::cerr << "[MQ][SEND_FAIL] unknown exception" << std::endl;
|
||||||
|
|
||||||
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_MQ,
|
||||||
|
"【ERROR】前置的%s%d号进程 mq发送失败,未知错误,请检查mq配置",
|
||||||
|
get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 析构函数中关闭并销毁生产者
|
// 析构函数中关闭并销毁生产者
|
||||||
~RocketMQProducer() {
|
~RocketMQProducer() {
|
||||||
if (producer_) {
|
/*if (producer_) {
|
||||||
ShutdownProducer(producer_);
|
ShutdownProducer(producer_);
|
||||||
DestroyProducer(producer_);
|
DestroyProducer(producer_);
|
||||||
std::cout << "rocketmq_Producer shutdown and destroyed." << std::endl;
|
std::cout << "rocketmq_Producer shutdown and destroyed." << std::endl;
|
||||||
|
}*/
|
||||||
|
try {
|
||||||
|
producer_.shutdown();
|
||||||
}
|
}
|
||||||
|
catch (...) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "rocketmq_Producer shutdown and destroyed." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CProducer* producer_;
|
//CProducer* producer_;
|
||||||
|
rocketmq::DefaultMQProducer producer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 全局生产者实例
|
// 全局生产者实例
|
||||||
@@ -513,7 +829,7 @@ void InitializeProducer()
|
|||||||
{
|
{
|
||||||
if (g_producer == NULL) {
|
if (g_producer == NULL) {
|
||||||
try {
|
try {
|
||||||
g_producer = new RocketMQProducer(G_ROCKETMQ_PRODUCER, G_ROCKETMQ_IPPORT);
|
g_producer = new RocketMQProducer(G_ROCKETMQ_PRODUCER, G_ROCKETMQ_IPPORT);//生产者名称和NameServer地址
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "Failed to initialize producer: " << e.what() << std::endl;
|
std::cerr << "Failed to initialize producer: " << e.what() << std::endl;
|
||||||
@@ -533,43 +849,37 @@ void ShutdownAndDestroyProducer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送消息的接口函数
|
// 发送消息的接口函数
|
||||||
void rocketmq_producer_send(const char* strbody, const char* topic)
|
void rocketmq_producer_send(const std::string& body,
|
||||||
|
const std::string& topic,
|
||||||
|
const std::string& tags,
|
||||||
|
const std::string& keys)
|
||||||
{
|
{
|
||||||
if (g_producer == NULL) {
|
std::call_once(g_producer_once, [&](){
|
||||||
try {
|
InitializeProducer();
|
||||||
InitializeProducer();
|
});
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
std::cerr << "Cannot send message because producer initialization failed." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 假设 tags 和 keys 是固定的,可以根据需要修改
|
|
||||||
std::string tags = G_ROCKETMQ_TAG;
|
|
||||||
std::string keys = G_ROCKETMQ_KEY;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
g_producer->sendMessage(strbody, topic, tags, keys);
|
g_producer->sendMessage(body, topic, tags, keys);
|
||||||
}
|
} catch (const std::exception& e) {
|
||||||
catch (const std::exception& e) {
|
|
||||||
std::cerr << "Failed to send message: " << e.what() << std::endl;
|
std::cerr << "Failed to send message: " << e.what() << std::endl;
|
||||||
// 处理发送失败的情况,例如记录日志或重试
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_MQ,
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 mq发送失败,请检查mq配置", get_front_msg_from_subdir(), g_front_seg_index);
|
"【ERROR】前置的%s%d号进程 mq发送失败,请检查mq配置",
|
||||||
|
get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
// producer_send0测试用
|
// producer_send0测试用
|
||||||
void StartSendMessage(CProducer* producer)
|
void StartSendMessage(CProducer* producer)
|
||||||
{
|
{
|
||||||
CSendResult result;
|
CSendResult result;
|
||||||
|
|
||||||
// create message and set some values for it
|
// create message and set some values for it
|
||||||
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC.c_str());
|
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC_TEST.c_str());
|
||||||
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
|
SetMessageTags(msg, G_ROCKETMQ_TAG_TEST.c_str());
|
||||||
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
|
SetMessageKeys(msg, G_ROCKETMQ_KEY_TEST.c_str());
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
@@ -593,9 +903,9 @@ void StartSendMessage(CProducer* producer,const char* strbody)
|
|||||||
CSendResult result;
|
CSendResult result;
|
||||||
|
|
||||||
// create message and set some values for it
|
// create message and set some values for it
|
||||||
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC.c_str());
|
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC_TEST.c_str());
|
||||||
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
|
SetMessageTags(msg, G_ROCKETMQ_TAG_TEST.c_str());
|
||||||
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
|
SetMessageKeys(msg, G_ROCKETMQ_KEY_TEST.c_str());
|
||||||
|
|
||||||
SetMessageBody(msg, strbody);
|
SetMessageBody(msg, strbody);
|
||||||
// send message
|
// send message
|
||||||
@@ -645,36 +955,36 @@ void producer_send(const char* strbody)
|
|||||||
DestroyProducer(producer);
|
DestroyProducer(producer);
|
||||||
cout << "Producer Shutdown!" << endl;
|
cout << "Producer Shutdown!" << endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern std::string G_MQCONSUMER_TOPIC_RT;
|
//extern std::string G_MQCONSUMER_TOPIC_RT;
|
||||||
void rocketmq_test_rt()
|
void rocketmq_test_rt()
|
||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_RT);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_RT);
|
||||||
std::ifstream file("rt.txt"); // 文件中存储长字符串
|
std::ifstream file("rt.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
extern std::string G_MQCONSUMER_TOPIC_UD;
|
//extern std::string G_MQCONSUMER_TOPIC_UD;
|
||||||
void rocketmq_test_ud()//用来测试台账更新
|
void rocketmq_test_ud()//用来测试台账更新
|
||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_UD);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_UD);
|
||||||
std::ifstream file("ud.txt"); // 文件中存储长字符串
|
std::ifstream file("ud.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,13 +992,13 @@ void rocketmq_test_set()//用来测试进程控制脚本
|
|||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_SET);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_SET);
|
||||||
std::ifstream file("set.txt"); // 文件中存储长字符串
|
std::ifstream file("set.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,43 +1006,43 @@ void rocketmq_test_only()//用来测试进程控制脚本
|
|||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_SET);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_TEST);
|
||||||
std::ifstream file("set_debug.txt"); // 文件中存储长字符串
|
std::ifstream file("test.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern std::string G_MQCONSUMER_TOPIC_RC;
|
//extern std::string G_MQCONSUMER_TOPIC_RC;
|
||||||
void rocketmq_test_rc()
|
void rocketmq_test_rc()
|
||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_RC);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_RC);
|
||||||
std::ifstream file("rc.txt"); // 文件中存储长字符串
|
std::ifstream file("rc.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern std::string G_MQCONSUMER_TOPIC_LOG;
|
//extern std::string G_MQCONSUMER_TOPIC_LOG;
|
||||||
void rocketmq_test_log()
|
void rocketmq_test_log()
|
||||||
{
|
{
|
||||||
Ckafka_data_t data;
|
Ckafka_data_t data;
|
||||||
data.monitor_id = 123123;
|
data.monitor_id = 123123;
|
||||||
data.strTopic = QString::fromStdString(std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_LOG);
|
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_LOG);
|
||||||
std::ifstream file("log_test.txt"); // 文件中存储长字符串
|
std::ifstream file("log_test.txt"); // 文件中存储长字符串
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << file.rdbuf(); // 读取整个文件内容
|
buffer << file.rdbuf(); // 读取整个文件内容
|
||||||
|
|
||||||
data.strText = QString::fromStdString(buffer.str());
|
data.strText = QString::fromStdString(buffer.str());
|
||||||
data.mp_id = 123123;
|
data.mp_id = QString::number(123456);
|
||||||
my_rocketmq_send(data);
|
my_rocketmq_send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
#include "../log4cplus/fileappender.h"
|
#include "../log4cplus/fileappender.h"
|
||||||
#include "../log4cplus/layout.h"
|
#include "../log4cplus/layout.h"
|
||||||
#include "../log4cplus/ndc.h"
|
#include "../log4cplus/ndc.h"
|
||||||
#include "../log4cplus/log4.h"
|
//#include "../log4cplus/log4.h"
|
||||||
#include "../log4cplus/spi/loggingevent.h"
|
#include "../log4cplus/spi/loggingevent.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -18,21 +18,47 @@
|
|||||||
//目录创建
|
//目录创建
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
//kafka结构定义
|
|
||||||
#include "../json/mms_json_inter.h"
|
#include "../json/mms_json_inter.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../mms/rdb_client.h"
|
#include "../mms/rdb_client.h"
|
||||||
#include "../include/node.h"//lnk20241223
|
#include "../include/node.h"//lnk20241223
|
||||||
|
|
||||||
|
#include "../log4cplus/log4.h"//后移防止min/max定义冲突
|
||||||
|
///////////////////////////////////////////////lnk20260303添加日志上送控制
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct LogLevelCache { //记录日志等级的缓存,减少频繁访问全局map的开销
|
||||||
|
std::unordered_map<std::string, int> term_min; // terminal_id -> min level
|
||||||
|
std::unordered_map<std::string, int> mp_min; // mp_id -> min level
|
||||||
|
};
|
||||||
|
|
||||||
|
// append线程只读,不加锁
|
||||||
|
static std::shared_ptr<LogLevelCache> g_level_cache_sp;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
//用来控制日志上送的结构
|
||||||
|
struct LOGEntry {
|
||||||
|
std::string id;
|
||||||
|
std::string level; // terminal / measurepoint
|
||||||
|
int code; //code
|
||||||
|
int min_grade; //允许上送的最低日志等级
|
||||||
|
int countdown; //自动关闭的倒计时,单位秒
|
||||||
|
};
|
||||||
|
|
||||||
|
//日志上送map管理
|
||||||
|
std::map<std::string, LOGEntry> g_log_entries;
|
||||||
|
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
/////////////////////////////////////////////外部定义
|
||||||
extern unsigned int g_node_id;
|
extern unsigned int g_node_id;
|
||||||
extern int g_front_seg_index;
|
extern int g_front_seg_index;
|
||||||
extern std::string FRONT_INST;
|
extern std::string FRONT_INST;
|
||||||
extern char subdir[128];
|
extern char subdir[128];
|
||||||
extern node_t* g_node;
|
extern node_t* g_node;
|
||||||
|
|
||||||
|
|
||||||
//mq
|
//mq
|
||||||
extern QMutex kafka_data_list_mutex; //Kafka发送数据锁
|
extern QMutex kafka_data_list_mutex; //Kafka发送数据锁
|
||||||
extern QList<Ckafka_data_t> kafka_data_list; //kafka发送数据链表
|
extern QList<Ckafka_data_t> kafka_data_list; //kafka发送数据链表
|
||||||
@@ -43,11 +69,161 @@ extern std::string intToString(int number);
|
|||||||
//日志主题
|
//日志主题
|
||||||
extern std::string G_LOG_TOPIC;
|
extern std::string G_LOG_TOPIC;
|
||||||
|
|
||||||
|
// 日志限流配置
|
||||||
|
extern int G_LOG_RATE_RESET_SEC;
|
||||||
|
extern int G_LOG_RATE_LIMIT_SEC;
|
||||||
|
extern int G_LOG_RATE_KEEP_ALL_MS;
|
||||||
|
extern int G_LOG_RATE_KEEP_BURST_MS;
|
||||||
|
extern int G_LOG_RATE_KEEP_BURST_COUNT;
|
||||||
|
extern int G_LOG_RATE_KEEP_HIGHFREQ_COUNT;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
//log4命名空间
|
//log4命名空间
|
||||||
using namespace log4cplus;
|
using namespace log4cplus;
|
||||||
using namespace log4cplus::helpers;
|
using namespace log4cplus::helpers;
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
static std::string extract_logger_id(const std::string& logger_name);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////辅助函数
|
////////////////////////////////////////////////////////辅助函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////lnk20260303添加日志上送控制
|
||||||
|
//用于在台账中查询日志上送控制项的日志等级字符串转换为整数
|
||||||
|
static int int_to_loglevel(int v, int default_level = WARN_LOG_LEVEL)
|
||||||
|
{
|
||||||
|
switch (v) {
|
||||||
|
case 0: return ERROR_LOG_LEVEL;
|
||||||
|
case 1: return WARN_LOG_LEVEL;
|
||||||
|
case 2: return INFO_LOG_LEVEL;
|
||||||
|
case 3: return DEBUG_LOG_LEVEL;
|
||||||
|
default: return default_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 构建日志等级缓存,减少 append 线程访问全局 map 的开销
|
||||||
|
static LogLevelCache* build_cache_unlocked()
|
||||||
|
{
|
||||||
|
LogLevelCache* nc = new LogLevelCache;
|
||||||
|
|
||||||
|
// 没 node / 没 clients:返回空 cache(查不到会兜底 WARN)
|
||||||
|
if (!g_node || g_node->n_clients <= 0 || !g_node->clients) {
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 你 LD_info 是固定 10 个就用 10;如果不是,改成实际长度
|
||||||
|
const int MAX_LD = 10;
|
||||||
|
|
||||||
|
for (int iedno = 0; iedno < g_node->n_clients; ++iedno) {
|
||||||
|
ied_t* ied = g_node->clients[iedno];
|
||||||
|
if (!ied || !ied->usr_ext) continue;
|
||||||
|
|
||||||
|
ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext;
|
||||||
|
|
||||||
|
// terminal_id 必须有效
|
||||||
|
const char* tid = ied_usr->terminal_id;
|
||||||
|
if (!tid || tid[0] == '\0') continue;
|
||||||
|
|
||||||
|
const std::string terminal_id(tid);
|
||||||
|
|
||||||
|
// 装置级阈值:0~3 -> log4cplus level(默认 WARN)
|
||||||
|
const int term_lv = int_to_loglevel(ied_usr->log_level, WARN_LOG_LEVEL);
|
||||||
|
nc->term_min[terminal_id] = term_lv;
|
||||||
|
|
||||||
|
// 监测点阈值:若非法/缺失,兜底用装置级 term_lv
|
||||||
|
for (int i = 0; i < MAX_LD; ++i) {
|
||||||
|
const char* mp = ied_usr->LD_info[i].mp_id;
|
||||||
|
if (!mp || mp[0] == '\0') continue;
|
||||||
|
|
||||||
|
const std::string mp_id(mp);
|
||||||
|
|
||||||
|
// mp 的 log_level 优先;非法则用 term_lv
|
||||||
|
const int mp_lv = int_to_loglevel(ied_usr->LD_info[i].log_level, term_lv);
|
||||||
|
nc->mp_min[mp_id] = mp_lv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
//用于更新日志等级缓存的函数,获取最新的日志上送控制项并更新到缓存中,调用时需持锁
|
||||||
|
void refresh_log_level_cache_locked()
|
||||||
|
{
|
||||||
|
std::shared_ptr<LogLevelCache> nc(build_cache_unlocked());
|
||||||
|
std::atomic_store(&g_level_cache_sp, nc);
|
||||||
|
}
|
||||||
|
const int LOGTYPE_DEFAULT = LOG_CODE_OTHER; // 默认日志类型,表示不区分具体类型的日志上送控制
|
||||||
|
static const int LOGTYPE_WILDCARD = 999; // 用于匹配任意日志类型的特殊值
|
||||||
|
static const char* ID_WILDCARD = "all"; // 用于匹配任意 ID 的特殊值
|
||||||
|
|
||||||
|
static std::string build_debug_key(const std::string& id,
|
||||||
|
const std::string& level, // terminal/measurepoint/process
|
||||||
|
int code) // 日志类型
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << id << "|" << level << "|" << code;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool find_entry_allow(const std::string& key, int level_val)
|
||||||
|
{
|
||||||
|
std::map<std::string, LOGEntry>::iterator it = g_log_entries.find(key);
|
||||||
|
if (it == g_log_entries.end() || it->second.countdown <= 0) return false;
|
||||||
|
return level_val >= it->second.min_grade;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool allow_low_level_send(const std::string& id,
|
||||||
|
const std::string& level_str,
|
||||||
|
int code,
|
||||||
|
int level_val)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&g_log_mutex);
|
||||||
|
|
||||||
|
// 1) 精确
|
||||||
|
if (find_entry_allow(build_debug_key(id, level_str, code), level_val)) {
|
||||||
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 2) logtype 通配
|
||||||
|
if (find_entry_allow(build_debug_key(id, level_str, LOGTYPE_WILDCARD), level_val)) {
|
||||||
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 3) id 通配
|
||||||
|
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, code), level_val)) {
|
||||||
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 4) 双通配
|
||||||
|
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, LOGTYPE_WILDCARD), level_val)) {
|
||||||
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_min_send_level_cached(const std::string& level_str, const std::string& logger_name)
|
||||||
|
{
|
||||||
|
const int DEFAULT_LEVEL = WARN_LOG_LEVEL;
|
||||||
|
if (level_str == "process") return DEFAULT_LEVEL;
|
||||||
|
|
||||||
|
const std::string id = extract_logger_id(logger_name); //terminal.<id> / monitor.<mp>
|
||||||
|
if (id.empty()) return DEFAULT_LEVEL;
|
||||||
|
|
||||||
|
std::shared_ptr<LogLevelCache> c = std::atomic_load(&g_level_cache_sp);
|
||||||
|
if (!c) return DEFAULT_LEVEL;
|
||||||
|
|
||||||
|
if (level_str == "terminal") {
|
||||||
|
auto it = c->term_min.find(id);
|
||||||
|
return (it != c->term_min.end()) ? it->second : DEFAULT_LEVEL;
|
||||||
|
}
|
||||||
|
if (level_str == "measurepoint") {
|
||||||
|
auto it = c->mp_min.find(id);
|
||||||
|
return (it != c->mp_min.end()) ? it->second : DEFAULT_LEVEL;
|
||||||
|
}
|
||||||
|
return DEFAULT_LEVEL;
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////lnk20260303添加日志上送控制
|
||||||
std::string get_front_type_from_subdir() {
|
std::string get_front_type_from_subdir() {
|
||||||
if (std::strstr(subdir, "cfg_3s_data") != NULL)
|
if (std::strstr(subdir, "cfg_3s_data") != NULL)
|
||||||
return "realTime";
|
return "realTime";
|
||||||
@@ -79,12 +255,11 @@ bool create_directory_recursive(const std::string& path) {
|
|||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
std::string extract_logger_id(const std::string& logger_name) {
|
std::string extract_logger_id(const std::string& logger_name) {
|
||||||
size_t first = logger_name.find('.');
|
if (logger_name == "process") return "process";
|
||||||
size_t last = logger_name.rfind('.');
|
size_t pos = logger_name.find('.');
|
||||||
if (first != std::string::npos && last != std::string::npos && first + 1 < last) {
|
if (pos == std::string::npos) return "";
|
||||||
return logger_name.substr(first + 1, last - first - 1); // 去掉开头"terminal."和结尾".COM"
|
// 取第一个 '.' 后面的全部:terminal.<id> / monitor.<mp>
|
||||||
}
|
return logger_name.substr(pos + 1);
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_level_str(int level) {
|
std::string get_level_str(int level) {
|
||||||
@@ -98,7 +273,7 @@ std::string get_level_str(int level) {
|
|||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
TypedLogger::TypedLogger() {}
|
TypedLogger::TypedLogger() {}
|
||||||
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), logtype(t) {}
|
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), code(t) {}
|
||||||
|
|
||||||
DebugSwitch::DebugSwitch() : debug_open(false), min_level(WARN_LOG_LEVEL) {}
|
DebugSwitch::DebugSwitch() : debug_open(false), min_level(WARN_LOG_LEVEL) {}
|
||||||
void DebugSwitch::open() { debug_open = true; }
|
void DebugSwitch::open() { debug_open = true; }
|
||||||
@@ -127,43 +302,86 @@ bool DebugSwitch::match(const std::string& logger_name, int level, int logtype)
|
|||||||
std::map<std::string, TypedLogger> logger_map;
|
std::map<std::string, TypedLogger> logger_map;
|
||||||
DebugSwitch g_debug_switch;
|
DebugSwitch g_debug_switch;
|
||||||
|
|
||||||
|
// ★新增:定义 TLS 变量,默认 0
|
||||||
|
LOG_TLS int g_log_code_tls = 0;
|
||||||
|
|
||||||
class SendAppender : public Appender {
|
class SendAppender : public Appender {
|
||||||
protected:
|
protected:
|
||||||
void append(const spi::InternalLoggingEvent& event) {
|
void append(const spi::InternalLoggingEvent& event) override {
|
||||||
std::string logger_name = event.getLoggerName();
|
std::string logger_name = event.getLoggerName();
|
||||||
int level = event.getLogLevel();
|
int level = event.getLogLevel();
|
||||||
std::string msg = event.getMessage();
|
std::string msg = event.getMessage();
|
||||||
|
|
||||||
int logtype = (logger_name.find(".COM") != std::string::npos) ? LOGTYPE_COM : LOGTYPE_DATA;
|
|
||||||
std::string level_str;
|
std::string level_str;
|
||||||
if (logger_name.find("process") == 0)
|
if (logger_name.find("process") == 0)
|
||||||
level_str = "process";
|
level_str = "process";
|
||||||
else if (logger_name.find("monitor") != std::string::npos)
|
else if (logger_name.find("monitor") != std::string::npos)
|
||||||
level_str = "measurepoint";
|
level_str = "measurepoint";
|
||||||
else
|
else if (logger_name.find("terminal") != std::string::npos)
|
||||||
level_str = "terminal";
|
level_str = "terminal";
|
||||||
|
else
|
||||||
|
level_str = "process";
|
||||||
|
|
||||||
if (level == ERROR_LOG_LEVEL || level == WARN_LOG_LEVEL || g_debug_switch.match(logger_name, level, logtype)) {
|
int code = g_log_code_tls; // TLS code
|
||||||
std::ostringstream oss;
|
int safe_logtype = code; // ★关键:用 code 当 logtype 维度
|
||||||
oss << "{\"processNo\":\"" << intToString(g_front_seg_index)
|
|
||||||
<< "\",\"nodeId\":\"" << FRONT_INST
|
|
||||||
<< "\",\"businessId\":\"" << extract_logger_id(logger_name)
|
|
||||||
<< "\",\"level\":\"" << level_str
|
|
||||||
<< "\",\"grade\":\"" << get_level_str(level)
|
|
||||||
<< "\",\"logtype\":\"" << (logtype == LOGTYPE_COM ? "com" : "data")
|
|
||||||
<< "\",\"frontType\":\"" << get_front_type_from_subdir()
|
|
||||||
<< "\",\"log\":\"" << escape_json(msg) << "\"}";
|
|
||||||
|
|
||||||
std::string jsonString = oss.str();
|
bool allow_send = false;
|
||||||
|
int min_send_level = get_min_send_level_cached(level_str, logger_name);
|
||||||
|
|
||||||
Ckafka_data_t connect_info;
|
// ① 高于台账阈值:直接上送
|
||||||
connect_info.strTopic = QString::fromStdString(G_LOG_TOPIC);
|
if (level >= min_send_level) {
|
||||||
connect_info.strText = QString::fromStdString(jsonString);
|
allow_send = true;
|
||||||
|
} else {
|
||||||
|
// ② 低等级:默认不上送,除非命令打开
|
||||||
|
std::string ctrl_id;
|
||||||
|
if (level_str == "process") ctrl_id = "process";
|
||||||
|
else ctrl_id = extract_logger_id(logger_name);
|
||||||
|
|
||||||
kafka_data_list_mutex.lock();
|
if (!ctrl_id.empty()) {
|
||||||
kafka_data_list.append(connect_info);
|
allow_send = allow_low_level_send(ctrl_id, level_str, safe_logtype, level);
|
||||||
kafka_data_list_mutex.unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!allow_send) return;
|
||||||
|
|
||||||
|
// ③ 限频:同一条日志
|
||||||
|
const std::string rkey = make_key(logger_name, level, code, msg);
|
||||||
|
|
||||||
|
uint64_t suppressed_before_emit = 0;
|
||||||
|
if (!should_emit(rkey, suppressed_before_emit)) return;
|
||||||
|
|
||||||
|
// 如果本次输出前压掉过日志,则在 log 文本后追加统计
|
||||||
|
std::string final_msg = msg;
|
||||||
|
if (suppressed_before_emit > 0) {
|
||||||
|
std::ostringstream suppressed_oss;
|
||||||
|
suppressed_oss << msg << " 【已过滤重复同类日志 "
|
||||||
|
<< suppressed_before_emit
|
||||||
|
<< " 条】";
|
||||||
|
final_msg = suppressed_oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string business_id = extract_logger_id(logger_name);
|
||||||
|
std::string front_type = get_front_type_from_subdir();
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "{\"processNo\":\"" << intToString(g_front_seg_index)
|
||||||
|
<< "\",\"nodeId\":\"" << escape_json(FRONT_INST)
|
||||||
|
<< "\",\"businessId\":\"" << escape_json(business_id)
|
||||||
|
<< "\",\"level\":\"" << escape_json(level_str)
|
||||||
|
<< "\",\"grade\":\"" << escape_json(get_level_str(level))
|
||||||
|
<< "\",\"logtype\":\"" << safe_logtype
|
||||||
|
<< "\",\"frontType\":\"" << escape_json(front_type)
|
||||||
|
<< "\",\"code\":" << code
|
||||||
|
<< ",\"log\":\"" << escape_json(final_msg) << "\"}";
|
||||||
|
|
||||||
|
Ckafka_data_t connect_info;
|
||||||
|
connect_info.strTopic = QString::fromStdString(G_LOG_TOPIC);
|
||||||
|
connect_info.mp_id = QString::fromStdString(business_id);
|
||||||
|
connect_info.strText = QString::fromStdString(oss.str());
|
||||||
|
|
||||||
|
kafka_data_list_mutex.lock();
|
||||||
|
kafka_data_list.append(connect_info);
|
||||||
|
kafka_data_list_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string escape_json(const std::string& input) {
|
std::string escape_json(const std::string& input) {
|
||||||
@@ -190,25 +408,128 @@ public:
|
|||||||
virtual ~SendAppender() {
|
virtual ~SendAppender() {
|
||||||
destructorImpl(); // 重要!释放 log4cplus 基类资源
|
destructorImpl(); // 重要!释放 log4cplus 基类资源
|
||||||
}
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////20260303添加日志上送控制 - 频率限制实现
|
||||||
|
private:
|
||||||
|
struct RateState {
|
||||||
|
uint64_t pass_count; // 当前周期内已放行条数
|
||||||
|
uint64_t suppressed_count; // 当前被抑制条数
|
||||||
|
std::chrono::steady_clock::time_point last_emit;
|
||||||
|
std::chrono::steady_clock::time_point last_seen;
|
||||||
|
std::chrono::steady_clock::time_point last_reset;
|
||||||
|
bool has_emit;
|
||||||
|
|
||||||
|
RateState()
|
||||||
|
: pass_count(0),
|
||||||
|
suppressed_count(0),
|
||||||
|
last_emit(),
|
||||||
|
last_seen(),
|
||||||
|
last_reset(),
|
||||||
|
has_emit(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, RateState> s_rate_map;
|
||||||
|
static std::mutex s_rate_mutex;
|
||||||
|
|
||||||
|
static std::string make_key(const std::string& logger_name, int level, int code, const std::string& msg) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << logger_name << "|" << level << "|" << code ; //<< "|" << msg;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool should_emit(const std::string& key, uint64_t& suppressed_before_emit) {
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
const auto now = steady_clock::now();
|
||||||
|
suppressed_before_emit = 0;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lk(s_rate_mutex);
|
||||||
|
RateState& st = s_rate_map[key];
|
||||||
|
|
||||||
|
const int RESET_SEC = G_LOG_RATE_RESET_SEC ; // 1小时重置
|
||||||
|
const int LIMIT_SEC = G_LOG_RATE_LIMIT_SEC ; // 进入限流后:多久发1条 主要控制中频和高频那些,低频的都直接放行了
|
||||||
|
|
||||||
|
// 初始化 / 强制每小时重置
|
||||||
|
if (st.last_reset.time_since_epoch().count() == 0) {
|
||||||
|
st.last_reset = now;
|
||||||
|
} else {
|
||||||
|
auto since_reset = duration_cast<seconds>(now - st.last_reset).count();
|
||||||
|
if (since_reset >= RESET_SEC) { //重置周期
|
||||||
|
st = RateState();
|
||||||
|
st.last_reset = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算当前频率档位(按“本次与上次看到该key的间隔”判断)
|
||||||
|
// >=60秒/条:全部保留
|
||||||
|
// [1秒, 60秒):保留前60条,然后1分钟1条
|
||||||
|
// <1秒:保留前10条,然后1分钟1条
|
||||||
|
int allow_burst = 0;
|
||||||
|
|
||||||
|
if (st.last_seen.time_since_epoch().count() == 0) {
|
||||||
|
// 第一次看到,先按“全部保留”处理
|
||||||
|
allow_burst = -1;
|
||||||
|
} else {
|
||||||
|
auto gap_ms = duration_cast<milliseconds>(now - st.last_seen).count();
|
||||||
|
|
||||||
|
if (gap_ms >= G_LOG_RATE_KEEP_ALL_MS) { //什么时候不需要限流 //低频 //如果这里设置的很低,就不会限流
|
||||||
|
allow_burst = -1; // 全部保留
|
||||||
|
} else if (gap_ms >= G_LOG_RATE_KEEP_BURST_MS) {
|
||||||
|
allow_burst = G_LOG_RATE_KEEP_BURST_COUNT; // 前60条 //中频 //如果这里设置的比低频低,也不会生效
|
||||||
|
} else {
|
||||||
|
allow_burst = G_LOG_RATE_KEEP_HIGHFREQ_COUNT; // 前10条 //高频
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st.last_seen = now;
|
||||||
|
|
||||||
|
// 档位1:全部保留
|
||||||
|
if (allow_burst == -1) {
|
||||||
|
suppressed_before_emit = st.suppressed_count;
|
||||||
|
st.suppressed_count = 0;
|
||||||
|
st.pass_count++;
|
||||||
|
st.last_emit = now;
|
||||||
|
st.has_emit = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 档位2/3:先放前N条
|
||||||
|
if (st.pass_count < (uint64_t)allow_burst) {
|
||||||
|
suppressed_before_emit = st.suppressed_count;
|
||||||
|
st.suppressed_count = 0;
|
||||||
|
st.pass_count++;
|
||||||
|
st.last_emit = now;
|
||||||
|
st.has_emit = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过前N条后:进入 1分钟1条
|
||||||
|
if (!st.has_emit) {
|
||||||
|
suppressed_before_emit = st.suppressed_count;
|
||||||
|
st.suppressed_count = 0;
|
||||||
|
st.pass_count++;
|
||||||
|
st.last_emit = now;
|
||||||
|
st.has_emit = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto elapsed = duration_cast<seconds>(now - st.last_emit).count();
|
||||||
|
if (elapsed >= LIMIT_SEC) {
|
||||||
|
suppressed_before_emit = st.suppressed_count;
|
||||||
|
st.suppressed_count = 0;
|
||||||
|
st.pass_count++;
|
||||||
|
st.last_emit = now;
|
||||||
|
st.has_emit = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本条被抑制
|
||||||
|
st.suppressed_count++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
//////////////////////////////////////////////////////////////////20260303添加日志上送控制 - 频率限制实现
|
||||||
//用来控制日志上送的结构
|
std::unordered_map<std::string, SendAppender::RateState> SendAppender::s_rate_map;
|
||||||
struct LOGEntry {
|
std::mutex SendAppender::s_rate_mutex;
|
||||||
std::string id;
|
|
||||||
std::string level; // terminal / measurepoint
|
|
||||||
int logtype; // com / data
|
|
||||||
int min_grade;
|
|
||||||
int countdown;
|
|
||||||
};
|
|
||||||
|
|
||||||
//日志上送map管理
|
|
||||||
std::map<std::string, LOGEntry> g_log_entries;
|
|
||||||
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
// 生成唯一 key
|
|
||||||
std::string build_debug_key(const std::string& id, const std::string& level, int logtype) {
|
|
||||||
return id + "|" + level + "|" + (logtype == 1 ? "COM" : "DATA");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 外部线程中调用:每秒更新所有倒计时,0 则删除
|
// 外部线程中调用:每秒更新所有倒计时,0 则删除
|
||||||
void update_log_entries_countdown() {
|
void update_log_entries_countdown() {
|
||||||
@@ -228,25 +549,25 @@ void update_log_entries_countdown() {
|
|||||||
pthread_mutex_unlock(&g_log_mutex);
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str) {
|
void process_log_command(const std::string& id,
|
||||||
if (level != "terminal" && level != "measurepoint") return;
|
const std::string& level,
|
||||||
|
const std::string& grade,
|
||||||
|
int code)
|
||||||
|
{
|
||||||
|
if (level != "terminal" && level != "measurepoint" && level != "process") return;
|
||||||
|
|
||||||
int type = (logtype_str == "com") ? LOGTYPE_COM : LOGTYPE_DATA;
|
|
||||||
int grade_level = (grade == "DEBUG") ? DEBUG_LOG_LEVEL : INFO_LOG_LEVEL;
|
int grade_level = (grade == "DEBUG") ? DEBUG_LOG_LEVEL : INFO_LOG_LEVEL;
|
||||||
|
|
||||||
std::string key = build_debug_key(id, level, type);
|
std::string key = build_debug_key(id, level, code);
|
||||||
|
|
||||||
pthread_mutex_lock(&g_log_mutex);
|
pthread_mutex_lock(&g_log_mutex);
|
||||||
|
LOGEntry& entry = g_log_entries[key];
|
||||||
LOGEntry& entry = g_log_entries[key]; // 会自动 insert 或取已有
|
|
||||||
entry.id = id;
|
entry.id = id;
|
||||||
entry.level = level;
|
entry.level = level;
|
||||||
entry.logtype = type;
|
entry.code = code;
|
||||||
entry.min_grade = grade_level;
|
entry.min_grade = grade_level;
|
||||||
entry.countdown = 60; // 重置倒计时
|
entry.countdown = 60;
|
||||||
|
|
||||||
pthread_mutex_unlock(&g_log_mutex);
|
pthread_mutex_unlock(&g_log_mutex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger init_logger(const std::string& full_name, const std::string& file_dir, const std::string& base_file, SharedAppenderPtr fileAppender) {
|
Logger init_logger(const std::string& full_name, const std::string& file_dir, const std::string& base_file, SharedAppenderPtr fileAppender) {
|
||||||
@@ -278,7 +599,7 @@ log4cplus::Logger init_logger(const std::string& full_name,
|
|||||||
//进程的日志
|
//进程的日志
|
||||||
void init_logger_process() {
|
void init_logger_process() {
|
||||||
std::string base_dir = std::string("/FeProject/") + subdir + "/processNo" + intToString(g_front_seg_index) + "/log";
|
std::string base_dir = std::string("/FeProject/") + subdir + "/processNo" + intToString(g_front_seg_index) + "/log";
|
||||||
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DATA);
|
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DEFAULT);
|
||||||
std::cout << "process log init ok" << std::endl;
|
std::cout << "process log init ok" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,12 +634,10 @@ void init_loggers_bydevid(const char* dev_id)
|
|||||||
|
|
||||||
std::string device_dir = base_dir + "/" + ip_str;
|
std::string device_dir = base_dir + "/" + ip_str;
|
||||||
|
|
||||||
std::string device_key_c = std::string("terminal.") + dev_id + ".COM";
|
std::string device_key = std::string("terminal.") + dev_id;
|
||||||
std::string device_key_d = std::string("terminal.") + dev_id + ".DATA";
|
|
||||||
|
|
||||||
// 添加判断:终端日志 logger 是否已存在
|
// 添加判断:终端日志 logger 是否已存在
|
||||||
if (logger_map.find(device_key_c) == logger_map.end() &&
|
if (logger_map.find(device_key) == logger_map.end()) {
|
||||||
logger_map.find(device_key_d) == logger_map.end()) {
|
|
||||||
|
|
||||||
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
||||||
std::string file_path_t = device_dir + "/" + dev_id + ".log";
|
std::string file_path_t = device_dir + "/" + dev_id + ".log";
|
||||||
@@ -327,27 +646,23 @@ void init_loggers_bydevid(const char* dev_id)
|
|||||||
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
||||||
device_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
device_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||||
|
|
||||||
Logger device_logger_c = init_logger(device_key_c, device_dir, dev_id, device_appender); //用终端id作为日志文件名
|
Logger device_logger = init_logger(device_key, device_dir, dev_id, device_appender); //用终端id作为日志文件名
|
||||||
Logger device_logger_d = init_logger(device_key_d, device_dir, dev_id, device_appender); //用终端id作为日志文件名
|
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
|
||||||
logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM);
|
|
||||||
logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA);
|
|
||||||
|
|
||||||
DIY_WARNLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
|
DIY_INFOLOG_CODE(device_key.c_str(),1,LOG_CODE_OTHER,"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化监测点
|
// 初始化监测点
|
||||||
// 监测点 logger 名称格式:monitor.<mp_id>.COM / .DATA
|
// 监测点 logger 名称格式:monitor.<mp_id>
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
|
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
|
||||||
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
|
std::ostringstream mon_key, mon_path, mon_name;
|
||||||
mon_key_c << "monitor." << ied_usr->LD_info[i].mp_id << ".COM";
|
mon_key << "monitor." << ied_usr->LD_info[i].mp_id;
|
||||||
mon_key_d << "monitor." << ied_usr->LD_info[i].mp_id << ".DATA";
|
|
||||||
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
|
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
|
||||||
mon_name << ied_usr->LD_info[i].mp_id;
|
mon_name << ied_usr->LD_info[i].mp_id;
|
||||||
|
|
||||||
// 添加判断:监测点 logger 是否已存在
|
// 添加判断:监测点 logger 是否已存在
|
||||||
if (logger_map.find(mon_key_c.str()) == logger_map.end() &&
|
if (logger_map.find(mon_key.str()) == logger_map.end()) {
|
||||||
logger_map.find(mon_key_d.str()) == logger_map.end()) {
|
|
||||||
|
|
||||||
// 所有监测点日志(com 和 data)写到同一个 monitor 日志文件中
|
// 所有监测点日志(com 和 data)写到同一个 monitor 日志文件中
|
||||||
std::string file_path_m = mon_path.str() + "/" + mon_name.str() + ".log";
|
std::string file_path_m = mon_path.str() + "/" + mon_name.str() + ".log";
|
||||||
@@ -356,12 +671,10 @@ void init_loggers_bydevid(const char* dev_id)
|
|||||||
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
||||||
monitor_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
monitor_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||||
|
|
||||||
Logger mon_logger_c = init_logger(mon_key_c.str(), mon_path.str(), mon_name.str(),monitor_appender);//用监测点号作为日志文件名
|
Logger mon_logger = init_logger(mon_key.str(), mon_path.str(), mon_name.str(),monitor_appender);//用监测点号作为日志文件名
|
||||||
Logger mon_logger_d = init_logger(mon_key_d.str(), mon_path.str(), mon_name.str(),monitor_appender);
|
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
|
||||||
logger_map[mon_key_c.str()] = TypedLogger(mon_logger_c, LOGTYPE_COM);
|
|
||||||
logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA);
|
|
||||||
|
|
||||||
DIY_WARNLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
|
DIY_INFOLOG_CODE(mon_key.str().c_str(),2,LOG_CODE_OTHER,"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,6 +682,9 @@ void init_loggers_bydevid(const char* dev_id)
|
|||||||
|
|
||||||
break; // 只匹配一个 terminal_id
|
break; // 只匹配一个 terminal_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lnk20260303添加日志上送控制 - 初始化时构建日志等级缓存
|
||||||
|
refresh_log_level_cache_locked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_loggers() {
|
void init_loggers() {
|
||||||
@@ -394,8 +710,7 @@ void init_loggers() {
|
|||||||
|
|
||||||
std::string device_dir = base_dir + "/" + ip_str;
|
std::string device_dir = base_dir + "/" + ip_str;
|
||||||
|
|
||||||
std::string device_key_c = std::string("terminal.") + ied_usr->terminal_id + ".COM";
|
std::string device_key = std::string("terminal.") + ied_usr->terminal_id;
|
||||||
std::string device_key_d = std::string("terminal.") + ied_usr->terminal_id + ".DATA";
|
|
||||||
|
|
||||||
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
||||||
std::string file_path_t = device_dir + "/" + ied_usr->terminal_id + ".log";
|
std::string file_path_t = device_dir + "/" + ied_usr->terminal_id + ".log";
|
||||||
@@ -404,21 +719,18 @@ void init_loggers() {
|
|||||||
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
||||||
device_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
device_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||||
|
|
||||||
Logger device_logger_c = init_logger(device_key_c, device_dir, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
|
Logger device_logger = init_logger(device_key, device_dir, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
|
||||||
Logger device_logger_d = init_logger(device_key_d, device_dir, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
|
|
||||||
|
|
||||||
logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM);
|
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
|
||||||
logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA);
|
|
||||||
|
|
||||||
DIY_WARNLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
|
DIY_INFOLOG_CODE(device_key.c_str(),1,LOG_CODE_OTHER,"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
|
||||||
|
|
||||||
// 初始化监测点
|
// 初始化监测点
|
||||||
// 监测点 logger 名称格式:monitor.<mp_id>.COM / .DATA
|
// 监测点 logger 名称格式:monitor.<mp_id>
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
|
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
|
||||||
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
|
std::ostringstream mon_key, mon_path, mon_name;
|
||||||
mon_key_c << "monitor." << ied_usr->LD_info[i].mp_id << ".COM";
|
mon_key << "monitor." << ied_usr->LD_info[i].mp_id;
|
||||||
mon_key_d << "monitor." << ied_usr->LD_info[i].mp_id << ".DATA";
|
|
||||||
|
|
||||||
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
|
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
|
||||||
mon_name << ied_usr->LD_info[i].mp_id;
|
mon_name << ied_usr->LD_info[i].mp_id;
|
||||||
@@ -429,19 +741,19 @@ void init_loggers() {
|
|||||||
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
||||||
monitor_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
monitor_appender->setLayout(std::auto_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||||
|
|
||||||
Logger mon_logger_c = init_logger(mon_key_c.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
Logger mon_logger = init_logger(mon_key.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
||||||
Logger mon_logger_d = init_logger(mon_key_d.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
|
||||||
|
|
||||||
logger_map[mon_key_c.str()] = TypedLogger(mon_logger_c, LOGTYPE_COM);
|
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
|
||||||
logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA);
|
|
||||||
|
|
||||||
DIY_WARNLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
|
DIY_INFOLOG_CODE(mon_key.str().c_str(),2,LOG_CODE_OTHER,"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//lnk20260303添加日志上送控制 - 初始化时构建日志等级缓存
|
||||||
|
refresh_log_level_cache_locked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_loggers_by_terminal_id(const char* terminal_id_cstr) {
|
void remove_loggers_by_terminal_id(const char* terminal_id_cstr) {
|
||||||
@@ -457,37 +769,24 @@ void remove_loggers_by_terminal_id(const char* terminal_id_cstr) {
|
|||||||
if (strcmp(ied_usr->terminal_id, terminal_id.c_str()) != 0) continue;
|
if (strcmp(ied_usr->terminal_id, terminal_id.c_str()) != 0) continue;
|
||||||
|
|
||||||
// 删除终端日志 logger
|
// 删除终端日志 logger
|
||||||
std::string com_key = "terminal." + terminal_id + ".COM";
|
std::string terminal_key = "terminal." + terminal_id;;
|
||||||
std::string data_key = "terminal." + terminal_id + ".DATA";
|
|
||||||
|
|
||||||
if (logger_map.count(com_key)) {
|
if (logger_map.count(terminal_key)) {
|
||||||
logger_map[com_key].logger.removeAllAppenders();
|
logger_map[terminal_key].logger.removeAllAppenders();
|
||||||
logger_map.erase(com_key);
|
logger_map.erase(terminal_key);
|
||||||
}
|
|
||||||
|
|
||||||
if (logger_map.count(data_key)) {
|
|
||||||
logger_map[data_key].logger.removeAllAppenders();
|
|
||||||
logger_map.erase(data_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除监测点日志 logger
|
// 删除监测点日志 logger
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
const char* mp_id = ied_usr->LD_info[i].mp_id;
|
const char* mp_id = ied_usr->LD_info[i].mp_id;
|
||||||
if (strlen(mp_id) > 0) {
|
if (strlen(mp_id) > 0) {
|
||||||
std::string mon_prefix = std::string("monitor.") + mp_id;
|
std::string mon_key = std::string("monitor.") + mp_id;
|
||||||
|
|
||||||
std::string mon_com_key = mon_prefix + ".COM";
|
if (logger_map.count(mon_key)) {
|
||||||
std::string mon_data_key = mon_prefix + ".DATA";
|
logger_map[mon_key].logger.removeAllAppenders();
|
||||||
|
logger_map.erase(mon_key);
|
||||||
if (logger_map.count(mon_com_key)) {
|
|
||||||
logger_map[mon_com_key].logger.removeAllAppenders();
|
|
||||||
logger_map.erase(mon_com_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger_map.count(mon_data_key)) {
|
|
||||||
logger_map[mon_data_key].logger.removeAllAppenders();
|
|
||||||
logger_map.erase(mon_data_key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +826,10 @@ extern "C" {
|
|||||||
send_reply_to_kafka(std::string(guid), std::string(step), std::string(result));
|
send_reply_to_kafka(std::string(guid), std::string(step), std::string(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_reply_to_kafka_recall_c(const char* guid, const char* step, const char* result,const char* lineIndex,const char* recallStartDate,const char* recallEndDate) {
|
||||||
|
send_reply_to_kafka_recall(std::string(guid), std::string(step), std::string(result),std::string(lineIndex), std::string(recallStartDate), std::string(recallEndDate));
|
||||||
|
}
|
||||||
|
|
||||||
//标准化日志接口
|
//标准化日志接口
|
||||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) {
|
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) {
|
||||||
// 写入时间
|
// 写入时间
|
||||||
|
|||||||
338
include/ied.h
338
include/ied.h
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @file: $RCSfile: ied.h,v $
|
* @file: $RCSfile: ied.h,v $
|
||||||
* @brief: $<EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD>ݽṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief: $设备数据结构定义
|
||||||
*
|
*
|
||||||
* @version: $Revision: 1.1 $
|
* @version: $Revision: 1.1 $
|
||||||
* @date: $Date: 2018/11/24 06:54:49 $
|
* @date: $Date: 2018/11/24 06:54:49 $
|
||||||
@@ -24,35 +24,35 @@ typedef byte_t channel_size_type;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define PRV_ANA_EXTENSION (1) //ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
#define PRV_ANA_EXTENSION (1) //模拟量用户扩展属性 总数
|
||||||
#define PRV_DIGIT_EXTENSION (3) //ң<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
#define PRV_DIGIT_EXTENSION (3) //遥信量用户扩展属性 总数
|
||||||
#define PRV_EVENT_EXTENSION (3) //<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
#define PRV_EVENT_EXTENSION (3) //事件量用户扩展属性 总数
|
||||||
#define PRV_PULSE_EXTENSION (2) //ң<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
#define PRV_PULSE_EXTENSION (2) //遥测量用户扩展属性 总数
|
||||||
//-----ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ---------------//
|
//-----模拟量用户扩展---------------//
|
||||||
#define ANA_EXTENSION_ALARM (0) //<EFBFBD>澯:<3A>澯<EFBFBD>ȼ<EFBFBD>;<3B>澯<EFBFBD><E6BEAF><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
#define ANA_EXTENSION_ALARM (0) //告警:告警等级;告警声音文件名
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct analog_t analog_t;
|
typedef struct analog_t analog_t;
|
||||||
struct analog_t {
|
struct analog_t {
|
||||||
byte_t type; /**< <EFBFBD><EFBFBD>ѹ/<2F><><EFBFBD><EFBFBD>/<2F>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD>/<2F><EFBFBD><DEB9><EFBFBD><EFBFBD><EFBFBD>/Ƶ<><C6B5>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD> */
|
byte_t type; /**< 电压/电流/有功功率/无功功率/频率/功率因素/其它 */
|
||||||
float initval; /**< ȱʡֵ */
|
float initval; /**< 缺省值 */
|
||||||
float minimum; /**< ȡֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
float minimum; /**< 取值下限 */
|
||||||
float maximum; /**< ȡֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
float maximum; /**< 取值上限 */
|
||||||
float step; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
float step; /**< 步长 */
|
||||||
byte_t integral; /**< precision ( n , m ) - n */
|
byte_t integral; /**< precision ( n , m ) - n */
|
||||||
byte_t decimal; /**< precision ( n , m ) - m */
|
byte_t decimal; /**< precision ( n , m ) - m */
|
||||||
float offset; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
float offset; /**< 实际值转换基数 */
|
||||||
float factor; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
float factor; /**< 实际值转换系数 */
|
||||||
float threshold; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
float threshold; /**< 门限值 */
|
||||||
float smooth; /**< ƽ<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
float smooth; /**< 平滑系数 */
|
||||||
float lower; /**< <EFBFBD>澯<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
float lower; /**< 告警下限值 */
|
||||||
float higher; /**< <EFBFBD>澯<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
float higher; /**< 告警上限值 */
|
||||||
float lowest; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯ֵ */
|
float lowest; /**< 下下限告警值 */
|
||||||
float highest; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯ֵ */
|
float highest; /**< 上上限告警值 */
|
||||||
float blur; /**< <EFBFBD><EFBFBD>ֵģ<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
float blur; /**< 阀值模糊系数 */
|
||||||
char dimension[SHORTNAME]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASCII<EFBFBD><EFBFBD>ʽ(A/V/kV/kvar/kW/MW etc.) */
|
char dimension[SHORTNAME]; /**< 量纲ASCII格式(A/V/kV/kvar/kW/MW etc.) */
|
||||||
void *ext[PRV_ANA_EXTENSION]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ */
|
void *ext[PRV_ANA_EXTENSION]; /**< 保护管理机扩展 */
|
||||||
}ALIGNPACKED;
|
}ALIGNPACKED;
|
||||||
|
|
||||||
|
|
||||||
@@ -66,27 +66,27 @@ struct ana_extention_t{
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct digit_t digit_t;
|
typedef struct digit_t digit_t;
|
||||||
#define DGT_TYP_UNDEF 0x00 /**< δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define DGT_TYP_UNDEF 0x00 /**< 未定义 */
|
||||||
#define DGT_TYP_SAMPLING 0x01 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define DGT_TYP_SAMPLING 0x01 /**< 采样 */
|
||||||
#define DGT_TYP_EVENT 0x02 /**< <EFBFBD>¼<EFBFBD> */
|
#define DGT_TYP_EVENT 0x02 /**< 事件 */
|
||||||
#define DGT_TYP_ALARM 0x03 /**< <EFBFBD>澯 */
|
#define DGT_TYP_ALARM 0x03 /**< 告警 */
|
||||||
#define DGT_TYP_OPERATE 0x04 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define DGT_TYP_OPERATE 0x04 /**< 操作 */
|
||||||
#define DGT_TYP_SYSTEM 0x05 /**< ϵͳ */
|
#define DGT_TYP_SYSTEM 0x05 /**< 系统 */
|
||||||
/** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
/** 数字量私有属性 */
|
||||||
struct digit_t {
|
struct digit_t {
|
||||||
byte_t type; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>¼<EFBFBD>/<2F>澯/<2F><><EFBFBD><EFBFBD>/ϵͳ */
|
byte_t type; /**< 采样/事件/告警/操作/系统 */
|
||||||
byte_t initval; /**< default zero value(0 or 1) */
|
byte_t initval; /**< default zero value(0 or 1) */
|
||||||
byte_t level; /**< level */
|
byte_t level; /**< level */
|
||||||
byte_t snd_timer; /**< sound play timer (s) */
|
byte_t snd_timer; /**< sound play timer (s) */
|
||||||
byte_t rst_timer; /**< auto restore timer (s) */
|
byte_t rst_timer; /**< auto restore timer (s) */
|
||||||
uint16_t act_lim; /**< (0 ==> 1)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint16_t act_lim; /**< (0 ==> 1)动作告警上限 */
|
||||||
uint16_t rst_lim; /**< (1 ==> 0)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint16_t rst_lim; /**< (1 ==> 0)动作告警上限 */
|
||||||
uint16_t act_num; /**< (0 ==> 1)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>) */
|
uint16_t act_num; /**< (0 ==> 1)动作上限(不需界面录入) */
|
||||||
uint16_t rst_num; /**< (1 ==> 0)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>) */
|
uint16_t rst_num; /**< (1 ==> 0)动作上限(不需界面录入) */
|
||||||
//<EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>
|
//第二版去掉
|
||||||
//char on[SHORTNAME]; /**< 0==>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(ASCII<EFBFBD><EFBFBD>ʽ) */
|
//char on[SHORTNAME]; /**< 0==>1动作名称(ASCII格式) */
|
||||||
//char off[SHORTNAME]; /**< 1==>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(ASCII<EFBFBD><EFBFBD>ʽ) */
|
//char off[SHORTNAME]; /**< 1==>0动作名称(ASCII格式) */
|
||||||
void *ext[PRV_DIGIT_EXTENSION]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ */
|
void *ext[PRV_DIGIT_EXTENSION]; /**< 保护管理机扩展 */
|
||||||
}ALIGNPACKED;
|
}ALIGNPACKED;
|
||||||
|
|
||||||
|
|
||||||
@@ -102,12 +102,12 @@ struct digit_t {
|
|||||||
|
|
||||||
typedef struct state_describe_extention_t state_describe_extention_t;
|
typedef struct state_describe_extention_t state_describe_extention_t;
|
||||||
struct state_describe_extention_t{
|
struct state_describe_extention_t{
|
||||||
char *state_describe[4]; /**< ״̬0<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char *state_describe[4]; /**< 状态0,1,2,3的描述 */
|
||||||
};
|
};
|
||||||
typedef struct sound_file_name_extention_t sound_file_name_extention_t;
|
typedef struct sound_file_name_extention_t sound_file_name_extention_t;
|
||||||
|
|
||||||
struct sound_file_name_extention_t{
|
struct sound_file_name_extention_t{
|
||||||
char *sound_file_name[3]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¹ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char *sound_file_name[3]; /**< 开报警声、合报警声、事故报警声 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct epfi_addt_extension_t epfi_addt_extension_t;
|
typedef struct epfi_addt_extension_t epfi_addt_extension_t;
|
||||||
@@ -120,48 +120,48 @@ struct epfi_addt_extension_t {
|
|||||||
|
|
||||||
typedef struct pulse_t pulse_t;
|
typedef struct pulse_t pulse_t;
|
||||||
/** Integrated totals private attr */
|
/** Integrated totals private attr */
|
||||||
#define PLS_TYP_UNDEF 0x00 /**< δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define PLS_TYP_UNDEF 0x00 /**< 未定义 */
|
||||||
#define PLS_TYP_PLUS_POWER_HV 0x01 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD> */
|
#define PLS_TYP_PLUS_POWER_HV 0x01 /**< 正向有功 */
|
||||||
#define PLS_TYP_PLUS_POWER_NO 0x02 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define PLS_TYP_PLUS_POWER_NO 0x02 /**< 正向无功 */
|
||||||
#define PLS_TYP_NEGATIVE_POWER_HV 0x03 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD> */
|
#define PLS_TYP_NEGATIVE_POWER_HV 0x03 /**< 反向有功 */
|
||||||
#define PLS_TYP_NEGATIVE_POWER_NO 0x04 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define PLS_TYP_NEGATIVE_POWER_NO 0x04 /**< 反向无功 */
|
||||||
struct pulse_t {
|
struct pulse_t {
|
||||||
byte_t type; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
byte_t type; /**< 正向有功/正向无功/反向有功/反向无功 */
|
||||||
uint32_t save_flag; /**< <EFBFBD>洢<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t save_flag; /**< 存储标记 */
|
||||||
uint32_t initval; /**< default value */
|
uint32_t initval; /**< default value */
|
||||||
uint32_t minimum; /**< minimum value */
|
uint32_t minimum; /**< minimum value */
|
||||||
uint32_t maximum; /**< maximum value */
|
uint32_t maximum; /**< maximum value */
|
||||||
uint32_t step; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t step; /**< 步长 */
|
||||||
//changed by zhancg 2017-04-05 <EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>
|
//changed by zhancg 2017-04-05 配系数
|
||||||
// uint32_t offset; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
// uint32_t offset; /**< 实际值转换基数 */
|
||||||
// uint32_t factor; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
// uint32_t factor; /**< 实际值转换系数 */
|
||||||
// uint32_t threshold; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
// uint32_t threshold; /**< 门限值 */
|
||||||
// uint32_t smooth; /**< ƽ<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
// uint32_t smooth; /**< 平滑系数 */
|
||||||
float offset; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
float offset; /**< 实际值转换基数 */
|
||||||
float factor; /**< ʵ<EFBFBD><EFBFBD>ֵת<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
float factor; /**< 实际值转换系数 */
|
||||||
float threshold; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
float threshold; /**< 门限值 */
|
||||||
float smooth; /**< ƽ<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> */
|
float smooth; /**< 平滑系数 */
|
||||||
char dimension[SHORTNAME]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASCII<EFBFBD><EFBFBD>ʽ(kvar/kW/MW etc.) */
|
char dimension[SHORTNAME]; /**< 量纲ASCII格式(kvar/kW/MW etc.) */
|
||||||
void *ext[PRV_PULSE_EXTENSION];
|
void *ext[PRV_PULSE_EXTENSION];
|
||||||
}ALIGNPACKED;
|
}ALIGNPACKED;
|
||||||
typedef struct pluse_stage_limits_extention_t pluse_stage_limits_extention_t;
|
typedef struct pluse_stage_limits_extention_t pluse_stage_limits_extention_t;
|
||||||
struct pluse_stage_limits_extention_t{
|
struct pluse_stage_limits_extention_t{
|
||||||
uint32_t limits[3]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ,<2C>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>ֵ,<2C>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
uint32_t limits[3]; /**< 峰电度限值,日电度限值,月电度限值 */
|
||||||
};
|
};
|
||||||
typedef struct pluse_stage_const_extention_t pluse_stage_const_extention_t;
|
typedef struct pluse_stage_const_extention_t pluse_stage_const_extention_t;
|
||||||
struct pluse_stage_const_extention_t{
|
struct pluse_stage_const_extention_t{
|
||||||
char* stage[8]; /**< <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>1,<2C><>ʱ<EFBFBD><CAB1>2,<2C><>ʱ<EFBFBD><CAB1>3,<2C><>ʱ<EFBFBD><CAB1>4,<2C><>ʱ<EFBFBD><CAB1>1,<2C><>ʱ<EFBFBD><CAB1>2,<2C><>ʱ<EFBFBD><CAB1>3,<2C><>ʱ<EFBFBD><CAB1>4 */
|
char* stage[8]; /**< 峰时段1,峰时段2,峰时段3,峰时段4,谷时段1,谷时段2,谷时段3,谷时段4 */
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
typedef struct command_t command_t;
|
typedef struct command_t command_t;
|
||||||
/** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ */
|
/** 命令消息结构 */
|
||||||
struct command_t {
|
struct command_t {
|
||||||
ticks_t ticks; /**< Ticks when command generated */
|
ticks_t ticks; /**< Ticks when command generated */
|
||||||
apr_time_t tmlimit; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
apr_time_t tmlimit; /**< 命令执行完成的限制时间 */
|
||||||
byte_t state; /**< ACTIVE<EFBFBD><EFBFBD>FINISH or TIMEOUT */
|
byte_t state; /**< ACTIVE、FINISH or TIMEOUT */
|
||||||
byte_t channel; /**< command channel no */
|
byte_t channel; /**< command channel no */
|
||||||
byte_t flag; /**< General<EFBFBD><EFBFBD>System or Special */
|
byte_t flag; /**< General、System or Special */
|
||||||
byte_t typ; /**< Command TYPE(IEC60870-5-101) */
|
byte_t typ; /**< Command TYPE(IEC60870-5-101) */
|
||||||
uint32_t ied; /**< Controlled IED id */
|
uint32_t ied; /**< Controlled IED id */
|
||||||
uint32_t group; /**< Controlled group id */
|
uint32_t group; /**< Controlled group id */
|
||||||
@@ -173,65 +173,65 @@ struct command_t {
|
|||||||
|
|
||||||
|
|
||||||
/** status_t code definiens */
|
/** status_t code definiens */
|
||||||
#define STATUS_NORMAL 0 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define STATUS_NORMAL 0 /**< 正常 */
|
||||||
#define STATUS_NOINIT 1 /**< δ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD> */
|
#define STATUS_NOINIT 1 /**< 未初始化 */
|
||||||
#define STATUS_OVERTIME 2 /**< ͨ<EFBFBD>ų<EFBFBD>ʱ */
|
#define STATUS_OVERTIME 2 /**< 通信超时 */
|
||||||
#define STATUS_BREAKOFF 3 /**< ͨ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */
|
#define STATUS_BREAKOFF 3 /**< 通信中断 */
|
||||||
#define STATUS_BLOCKED 4 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define STATUS_BLOCKED 4 /**< 封锁 */
|
||||||
#define STATUS_TESTING 5 /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define STATUS_TESTING 5 /**< 测试 */
|
||||||
#define STATUS_NOTDEF 6 /**< δ<EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) */
|
#define STATUS_NOTDEF 6 /**< 未配置(本运行状态没有配置) */
|
||||||
|
|
||||||
typedef uint16_t status_t; /**< <EFBFBD>豸<EFBFBD><EFBFBD>ͨ<EFBFBD>Žڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬ */
|
typedef uint16_t status_t; /**< 设备或通信节点的运行状态 */
|
||||||
|
|
||||||
typedef struct alias_t alias_t;
|
typedef struct alias_t alias_t;
|
||||||
/** <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>صı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ */
|
/** 数据元素的别名结构 */
|
||||||
struct alias_t { /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>صı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ */
|
struct alias_t { /**< 数据元素的别名结构 */
|
||||||
uint32_t id; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>ַ */
|
uint32_t id; /**< 别名信息地址 */
|
||||||
uint32_t parent; /**< <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IED */
|
uint32_t parent; /**< 所指代的IED */
|
||||||
uint32_t group; /**< <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IED<EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t group; /**< 所指代的IED内的组号 */
|
||||||
uint32_t dot; /**< <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IED<EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t dot; /**< 所指代的IED内的序号 */
|
||||||
value_t* value; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
value_t* value; /**< 运行时刻实时数据 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ied_t ied_t;
|
typedef struct ied_t ied_t;
|
||||||
typedef struct group_t group_t;
|
typedef struct group_t group_t;
|
||||||
typedef struct element_t element_t;
|
typedef struct element_t element_t;
|
||||||
|
|
||||||
/** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϢԪ<EFBFBD>صĽṹ */
|
/** 数据信息元素的结构 */
|
||||||
struct element_t {
|
struct element_t {
|
||||||
uint32_t id; /**< Identification, Information Address */
|
uint32_t id; /**< Identification, Information Address */
|
||||||
uint32_t flags; /**< flags define */
|
uint32_t flags; /**< flags define */
|
||||||
byte_t type; /**< IEC60870-5-101 TYP.(IEC60870DEF.h) */
|
byte_t type; /**< IEC60870-5-101 TYP.(IEC60870DEF.h) */
|
||||||
byte_t code; /**< Data code type.(BIN/ASCII/BCD/etc.) */
|
byte_t code; /**< Data code type.(BIN/ASCII/BCD/etc.) */
|
||||||
uint32_t parent; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸 */
|
uint32_t parent; /**< 隶属设备 */
|
||||||
uint32_t group; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t group; /**< 数据组号 */
|
||||||
uint32_t dot; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t dot; /**< 数据序号 */
|
||||||
uint16_t size; /**< <EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA>λ) */
|
uint16_t size; /**< 数据宽度(以字节为单位) */
|
||||||
char name[LONGNAME]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char name[LONGNAME]; /**< 数据名称 */
|
||||||
|
|
||||||
char *aliasname; /**< <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>Ӧ<EFBFBD><EFBFBD>Ӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ++EPFI++ */
|
char *aliasname; /**< 数据点别名,如用于中文名称对应的英文名称 ++EPFI++ */
|
||||||
|
|
||||||
void *owner; /**< ˽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խṹ(analog_t/digit_t/..../etc.) */
|
void *owner; /**< 私有属性结构(analog_t/digit_t/..../etc.) */
|
||||||
void *script; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ */
|
void *script; /**< 关联的计算表达式 */
|
||||||
|
|
||||||
/** Runtime generate */
|
/** Runtime generate */
|
||||||
value_t value; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʵʱ<EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
value_t value; /**< 运行时刻实时数据缓冲区 */
|
||||||
ticks_t last; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>仯ʱ<EFBFBD><EFBFBD> */
|
ticks_t last; /**< 最后变化时间 */
|
||||||
uint32_t state; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬ */
|
uint32_t state; /**< 数据状态 */
|
||||||
byte_t funtype; /**< <EFBFBD>̳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD>ݹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
byte_t funtype; /**< 继承自所属组的类型,表示数据功能类型 */
|
||||||
uint16_t index; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint16_t index; /**< 数据元素索引 */
|
||||||
uint16_t n_alias_add_1; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С<EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD> */
|
uint16_t n_alias_add_1; /**< 分配的数据别名缓冲区的大小(预留1,动态定订购用) */
|
||||||
uint16_t n_alias; /**< <EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD> */
|
uint16_t n_alias; /**< 数据别名数组元素个数 */
|
||||||
alias_t* alias; /**< <EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
alias_t* alias; /**< 数据别名索引数组 */
|
||||||
uint16_t alias_pos; /**< <EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰλ<EFBFBD><EFBFBD> */
|
uint16_t alias_pos; /**< 数据别名当前位置 */
|
||||||
uint32_t offset; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ƫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t offset; /**< 数据在设备数据缓冲区内的偏移索引 */
|
||||||
group_t *grp; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
group_t *grp; /**< 所属数据组句柄 */
|
||||||
ied_t *ied; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
ied_t *ied; /**< 所属设备句柄 */
|
||||||
|
|
||||||
/* Extend property */
|
/* Extend property */
|
||||||
void *sys_ext; /**< <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *sys_ext; /**< 数据点的系统扩展属性,由基本库实现 */
|
||||||
void *app_ext; /**< <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>Ӧ<EFBFBD>ÿ<EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *app_ext; /**< 数据点的应用扩展属性,由应用库实现 */
|
||||||
void *usr_ext; /**< <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>Ӧ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *usr_ext; /**< 数据点的用户扩展属性,由应用程序实现 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** group_t->type definiens */
|
/** group_t->type definiens */
|
||||||
@@ -245,36 +245,36 @@ struct element_t {
|
|||||||
#define GRP_ALARM 7 /**< Alarm type */
|
#define GRP_ALARM 7 /**< Alarm type */
|
||||||
#define GRP_SETTING 8 /**< Fixed value type */
|
#define GRP_SETTING 8 /**< Fixed value type */
|
||||||
#define GRP_STATUS 9 /**< State of device */
|
#define GRP_STATUS 9 /**< State of device */
|
||||||
#define GRP_VDI 10 /**< <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD> type */
|
#define GRP_VDI 10 /**< 软压板 type */
|
||||||
#define GRP_STEPPOS 11 /**< Step position type */
|
#define GRP_STEPPOS 11 /**< Step position type */
|
||||||
#define GRP_COMBO 12 /**< combo/compute type */
|
#define GRP_COMBO 12 /**< combo/compute type */
|
||||||
#define GRP_SIMANA 13 /**< ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define GRP_SIMANA 13 /**< 模拟量 */
|
||||||
#define GRP_SETAREA 14 /**< <EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD> */
|
#define GRP_SETAREA 14 /**< 定值区 */
|
||||||
#define GRP_ACCANA 15 /**< ¼<EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define GRP_ACCANA 15 /**< 录波模拟量 */
|
||||||
#define GRP_ACCDGT 16 /**< ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define GRP_ACCDGT 16 /**< 录波开关量 */
|
||||||
#define GRP_SETPOINT 18 /**< Set point type for 101,104 protocol used only */
|
#define GRP_SETPOINT 18 /**< Set point type for 101,104 protocol used only */
|
||||||
#define GRP_STEPCONTROL 19 /**< <EFBFBD><EFBFBD>λ<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define GRP_STEPCONTROL 19 /**< 步位置调节组 */
|
||||||
|
|
||||||
/** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ */
|
/** 数据组结构 */
|
||||||
struct group_t {
|
struct group_t {
|
||||||
uint32_t id; /**< Identification, Commond Address of Set */
|
uint32_t id; /**< Identification, Commond Address of Set */
|
||||||
uint32_t flags; /**< Flags definiens */
|
uint32_t flags; /**< Flags definiens */
|
||||||
byte_t type; /**< Analogue/Digit/Control/Event/etc. */
|
byte_t type; /**< Analogue/Digit/Control/Event/etc. */
|
||||||
char name[LONGNAME]; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char name[LONGNAME]; /**< 数据组的名称 */
|
||||||
uint16_t maxelems; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>elements<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ */
|
uint16_t maxelems; /**< 允许包含elements的最大数目 */
|
||||||
element_t *elements; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
element_t *elements; /**< 数据元素定义数组 */
|
||||||
|
|
||||||
// runtime generate
|
// runtime generate
|
||||||
uint16_t count; /**< ʵ<EFBFBD>ʰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ */
|
uint16_t count; /**< 实际包含的数据元素数目 */
|
||||||
uint16_t index; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IED->groups<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD> */
|
uint16_t index; /**< 数据组索引IED->groups的数组下标 */
|
||||||
value_t value; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>黺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>elements<EFBFBD><EFBFBD>ʵʱֵ */
|
value_t value; /**< 数据组缓冲区,顺序存放elements的实时值 */
|
||||||
ied_t *ied; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
ied_t *ied; /**< 所属设备句柄 */
|
||||||
apr_hash_t *htdots; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD> */
|
apr_hash_t *htdots; /**< 数据元素定义哈希表 */
|
||||||
|
|
||||||
/* Extend property */
|
/* Extend property */
|
||||||
void *sys_ext; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *sys_ext; /**< 数据组的系统扩展属性,由基本库实现 */
|
||||||
void *app_ext; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>Ӧ<EFBFBD>ÿ<EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *app_ext; /**< 数据组的应用扩展属性,由应用库实现 */
|
||||||
void *usr_ext; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>Ӧ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD>ʵ<EFBFBD><CAB5> */
|
void *usr_ext; /**< 数据组的用户扩展属性,由应用程序实现 */
|
||||||
};
|
};
|
||||||
|
|
||||||
//<!-- IEDConfig id,name,flags,type,chncount,cpucount,addrsinfo,cpusinfo,station,frequency,delay,count
|
//<!-- IEDConfig id,name,flags,type,chncount,cpucount,addrsinfo,cpusinfo,station,frequency,delay,count
|
||||||
@@ -284,83 +284,83 @@ struct group_t {
|
|||||||
#define IED_TYPE_REMOTE (1)
|
#define IED_TYPE_REMOTE (1)
|
||||||
#define IED_TYPE_SYSTEM (2)
|
#define IED_TYPE_SYSTEM (2)
|
||||||
#define IED_TYPE_VIRTUAL (3)
|
#define IED_TYPE_VIRTUAL (3)
|
||||||
#define IED_TYPE_EPFI (4) /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define IED_TYPE_EPFI (4) /**< 保护管理机 */
|
||||||
|
|
||||||
|
|
||||||
#define IED_FLAG_BLOCKED 0x00000004 /**< <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱʡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define IED_FLAG_BLOCKED 0x00000004 /**< 是否封锁,缺省不封锁 */
|
||||||
|
|
||||||
|
|
||||||
#define CHANBEL_TYPE_UNKNOWN (0)
|
#define CHANBEL_TYPE_UNKNOWN (0)
|
||||||
#define CHANNEL_TYPE_IPV4 (1)
|
#define CHANNEL_TYPE_IPV4 (1)
|
||||||
#define CHANNEL_TYPE_IPV6 (2) /**< δ<EFBFBD><EFBFBD> */
|
#define CHANNEL_TYPE_IPV6 (2) /**< 未用 */
|
||||||
#define CHANNEL_TYPE_SERIAL (3) /**< <EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD> */
|
#define CHANNEL_TYPE_SERIAL (3) /**< 串口号 */
|
||||||
|
|
||||||
#define CHANNEL_TYPE_USER_DEFINED (254) /**< <EFBFBD>û<EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
#define CHANNEL_TYPE_USER_DEFINED (254) /**< 用户自定义类型 */
|
||||||
|
|
||||||
|
|
||||||
typedef struct channel_t channel_t;
|
typedef struct channel_t channel_t;
|
||||||
struct channel_t {
|
struct channel_t {
|
||||||
uint32_t master; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>(Node ID) */
|
uint32_t master; /**< 所属通信通道(Node ID) */
|
||||||
|
|
||||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ2008-08-16<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,֧<><D6A7>
|
//以下两个属性域为2008-08-16增加,支持
|
||||||
int channel_type; /**< ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
int channel_type; /**< 通道地址类型 */
|
||||||
char addr_str[LONGNAME]; /**< ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ */
|
char addr_str[LONGNAME]; /**< 通道地址的字符串表示 */
|
||||||
|
|
||||||
uint32_t addr; /**< ͨ<EFBFBD>Ŷ˿ڵ<EFBFBD>ַ */
|
uint32_t addr; /**< 通信端口地址 */
|
||||||
uint16_t port; /**< ip<EFBFBD><EFBFBD>ַ<EFBFBD>Ķ˿<EFBFBD> */
|
uint16_t port; /**< ip地址的端口 */
|
||||||
|
|
||||||
uint32_t status; /**< ͨ<EFBFBD>Ŷ˿<EFBFBD>״̬ */
|
uint32_t status; /**< 通信端口状态 */
|
||||||
ticks_t last_ticks; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
ticks_t last_ticks; /**< 最近访问时间 */
|
||||||
ticks_t last_send_ticks; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯʱ<EFBFBD><EFBFBD> */
|
ticks_t last_send_ticks; /**< 最近查询时间 */
|
||||||
void *connect; /**< ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><EFBFBD><EFBFBD> */
|
void *connect; /**< 通道连接句柄 */
|
||||||
ied_t *ied; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
ied_t *ied; /**< 所属设备句柄 */
|
||||||
int ied_id; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸id */
|
int ied_id; /**< 所属设备id */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct cpuinfo_t cpuinfo_t;
|
typedef struct cpuinfo_t cpuinfo_t;
|
||||||
struct cpuinfo_t {
|
struct cpuinfo_t {
|
||||||
byte_t addr; /**< CPU<EFBFBD><EFBFBD>ַ */
|
byte_t addr; /**< CPU地址 */
|
||||||
byte_t status; /**< CPU״̬ */
|
byte_t status; /**< CPU状态 */
|
||||||
byte_t templ; /**< CPUģ<EFBFBD><EFBFBD> */
|
byte_t templ; /**< CPU模板 */
|
||||||
char name[LONGNAME]; /**< CPU<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char name[LONGNAME]; /**< CPU名称 */
|
||||||
ticks_t last_gi; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>ѯʱ<EFBFBD><EFBFBD> */
|
ticks_t last_gi; /**< 最近总查询时间 */
|
||||||
ticks_t last_gi_send; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
ticks_t last_gi_send; /**< 最近总查询发送时间 */
|
||||||
ticks_t next_gi_send; /**< <EFBFBD>´<EFBFBD><EFBFBD>ܲ<EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
ticks_t next_gi_send; /**< 下次总查询发送时间 */
|
||||||
ticks_t last_ticks; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
ticks_t last_ticks; /**< 最近访问时间 */
|
||||||
ticks_t last_send_ticks; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯʱ<EFBFBD><EFBFBD> */
|
ticks_t last_send_ticks; /**< 最近查询时间 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** IED struct definiens */
|
/** IED struct definiens */
|
||||||
struct ied_t {
|
struct ied_t {
|
||||||
uint32_t id; /**< Primy key ( = 0 ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IED ) */
|
uint32_t id; /**< Primy key ( = 0 系统保留IED ) */
|
||||||
uint32_t flags; /**< Flags define */
|
uint32_t flags; /**< Flags define */
|
||||||
byte_t type; /**< Type define */
|
byte_t type; /**< Type define */
|
||||||
byte_t chncount; /**< <EFBFBD>豸ͨ<EFBFBD>Ŷ˿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱʡ=1<><31> */
|
byte_t chncount; /**< 设备通信端口总数(缺省=1) */
|
||||||
channel_t *channel; /**< <EFBFBD>豸ͨ<EFBFBD>Ŷ˿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
channel_t *channel; /**< 设备通信端口数组 */
|
||||||
byte_t cpucount; /**< CPU<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱʡ=1<><31> */
|
byte_t cpucount; /**< CPU总数(缺省=1) */
|
||||||
cpuinfo_t *cpuinfo; /**< CPU<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
cpuinfo_t *cpuinfo; /**< CPU地址数组 */
|
||||||
char name[LONGNAME]; /**< <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
char name[LONGNAME]; /**< 设备名称 */
|
||||||
uint32_t station; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>վ<EFBFBD><EFBFBD><ֱ<><D6B1>Ŀ¼ID> */
|
uint32_t station; /**< 所属站号<直属目录ID> */
|
||||||
uint32_t node; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>Žڵ<EFBFBD><EFBFBD><EFBFBD> */
|
uint32_t node; /**< 所属通信节点号 */
|
||||||
uint16_t frequency; /**< ͨ<EFBFBD><EFBFBD>ɨ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD> */
|
uint16_t frequency; /**< 通信扫描频率 */
|
||||||
uint32_t delay; /**< ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ʱ(ms) */
|
uint32_t delay; /**< 通信响应延时(ms) */
|
||||||
uint16_t count; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ */
|
uint16_t count; /**< 包含的数据组数目 */
|
||||||
group_t *groups; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鶨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
group_t *groups; /**< 数据组定义数组 */
|
||||||
apr_hash_t *htgroups; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鶨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
apr_hash_t *htgroups; /**< 数据组定义哈希表句柄 */
|
||||||
uint32_t systoken_st; /**< ϵͳ<EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>״̬ */
|
uint32_t systoken_st; /**< 系统令牌的状态 */
|
||||||
|
|
||||||
/* Runtime generate */
|
/* Runtime generate */
|
||||||
uint16_t index; /**< <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD> */
|
uint16_t index; /**< 设备数组下标 */
|
||||||
status_t status; /**< <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬ */
|
status_t status; /**< 设备运行状态 */
|
||||||
ticks_t last_ticks; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
|
ticks_t last_ticks; /**< 最近访问时间 */
|
||||||
ticks_t last_gi; /**< <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>ѯʱ<EFBFBD><EFBFBD> */
|
ticks_t last_gi; /**< 最近总查询时间 */
|
||||||
|
|
||||||
/* Extend property */
|
/* Extend property */
|
||||||
void *sys_ext; /**< <EFBFBD>豸<EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>ⶨ<EFBFBD><E2B6A8> */
|
void *sys_ext; /**< 设备的系统扩展属性,基本库定义 */
|
||||||
void *app_ext; /**< <EFBFBD>豸<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,Ӧ<>ÿⶨ<C3BF><E2B6A8> */
|
void *app_ext; /**< 设备的应用扩展属性,应用库定义 */
|
||||||
void *usr_ext; /**< <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,Ӧ<>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
void *usr_ext; /**< 设备的用户扩展属性,应用程序定义 */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _OS_WIN32_
|
#ifdef _OS_WIN32_
|
||||||
|
|||||||
@@ -224,8 +224,19 @@ extern "C" {
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
*/
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|||||||
@@ -1,21 +1,34 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include "../json/mms_json_inter.h"
|
#include "../json/mms_json_inter.h"
|
||||||
#include "../rocketmq/CProducer.h"
|
//#include "../rocketmq/CProducer.h"
|
||||||
#include "../rocketmq/CMessage.h"
|
//#include "../rocketmq/CMessage.h"
|
||||||
#include "../rocketmq/CSendResult.h"
|
//#include "../rocketmq/CSendResult.h"
|
||||||
|
//#include "../rocketmq/CPushConsumer.h"
|
||||||
#include "../rocketmq/CPushConsumer.h"
|
#include "../rocketmq/DefaultMQProducer.h"
|
||||||
|
#include "../rocketmq/MQMessage.h"
|
||||||
|
#include "../rocketmq/SendResult.h"
|
||||||
|
#include "../rocketmq/SessionCredentials.h"
|
||||||
|
#include "../rocketmq/MQMessageExt.h"
|
||||||
|
#include "../rocketmq/ConsumeType.h"
|
||||||
|
#include "../rocketmq/MQMessageListener.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace rocketmq;
|
||||||
|
|
||||||
/*添加测试函数lnk10-10*/
|
/*添加测试函数lnk10-10*/
|
||||||
void producer_send0();
|
//void producer_send0();
|
||||||
void StartSendMessage(CProducer* producer,const char* strbody);
|
//void StartSendMessage(CProducer* producer,const char* strbody);
|
||||||
void producer_send(const char* strbody);
|
//void producer_send(const char* strbody);
|
||||||
void rocketmq_producer_send(const char* strbody,const char* topic);
|
//void rocketmq_producer_send(const char* strbody,const char* topic);
|
||||||
void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic);
|
//void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic);
|
||||||
|
void rocketmq_producer_send(const std::string& body,
|
||||||
|
const std::string& topic,
|
||||||
|
const std::string& tags,
|
||||||
|
const std::string& keys);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void rocketmq_test_rt();
|
void rocketmq_test_rt();
|
||||||
void rocketmq_test_ud();
|
void rocketmq_test_ud();
|
||||||
@@ -32,24 +45,29 @@ extern void my_rocketmq_send(Ckafka_data_t& data);
|
|||||||
void InitializeProducer();
|
void InitializeProducer();
|
||||||
void ShutdownAndDestroyProducer();
|
void ShutdownAndDestroyProducer();
|
||||||
//////////////////////////////////////////////////////消费者
|
//////////////////////////////////////////////////////消费者
|
||||||
void InitializeConsumer(const std::string& consumerName, const std::string& nameServer, const char* topic, const char* tag, const std::string& key);
|
typedef ConsumeStatus (*MessageCallBack)(
|
||||||
void ShutdownAndDestroyConsumer();
|
const MQMessageExt& msg
|
||||||
|
);
|
||||||
|
|
||||||
struct Subscription {
|
struct Subscription {
|
||||||
std::string topic;
|
std::string topic;
|
||||||
std::string tag;
|
std::string tag;
|
||||||
MessageCallBack callback;
|
MessageCallBack callback;
|
||||||
|
|
||||||
Subscription(const std::string& t, const std::string& tg, MessageCallBack cb)
|
Subscription(const std::string& t,
|
||||||
|
const std::string& tg,
|
||||||
|
MessageCallBack cb)
|
||||||
: topic(t), tag(tg), callback(cb) {}
|
: topic(t), tag(tg), callback(cb) {}
|
||||||
};
|
};
|
||||||
|
//void InitializeConsumer(const std::string& consumerName, const std::string& nameServer, const char* topic, const char* tag, const std::string& key);
|
||||||
|
void InitializeConsumer(const std::string& consumerName,
|
||||||
|
const std::string& nameServer,
|
||||||
|
const std::vector<Subscription>& subscriptions);
|
||||||
|
void ShutdownAndDestroyConsumer();
|
||||||
|
|
||||||
void rocketmq_consumer_receive(
|
void rocketmq_consumer_receive(
|
||||||
const std::string& consumerName,
|
const std::string& consumerName,
|
||||||
const std::string& nameServer,
|
const std::string& nameServer,
|
||||||
//const std::string& topic,
|
|
||||||
//const std::string& tag,
|
|
||||||
//MessageCallBack callback);
|
|
||||||
const std::vector<Subscription>& subscriptions);
|
const std::vector<Subscription>& subscriptions);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
#ifndef HIBYTE
|
#ifndef HIBYTE
|
||||||
#define HIBYTE(w) ((byte_t)((uint16_t)(w) >> 8))
|
#define HIBYTE(w) ((byte_t)((uint16_t)(w) >> 8))
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
#ifndef max
|
#ifndef max
|
||||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
@@ -57,7 +57,18 @@
|
|||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1297
json/PQSMsg.cpp
Normal file
1297
json/PQSMsg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2548
json/PQSMsg.h
Normal file
2548
json/PQSMsg.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,18 @@
|
|||||||
#include "../json/cjson.h"
|
#include "../json/cjson.h"
|
||||||
|
|
||||||
#include "../log4cplus/log4.h"//lnk添加log4
|
#include "../log4cplus/log4.h"//lnk添加log4
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////lnk20260305数据追踪相关
|
||||||
|
#include <QHash>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QMapIterator>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
// ★MOD: 全局追踪表:mp_id -> remaining times
|
||||||
|
static QMutex g_trace_mutex;
|
||||||
|
static QHash<QString, int> g_trace_map;
|
||||||
|
|
||||||
///////////////////////////////////////////////////lnk2024-10-21////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////lnk2024-10-21////////////////////////////////////////////////////////
|
||||||
extern void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr);
|
extern void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr);
|
||||||
extern std::string WEB_INTEGRITY;
|
extern std::string WEB_INTEGRITY;
|
||||||
@@ -33,6 +45,11 @@ extern std::string WEB_EVENT;
|
|||||||
extern std::string WEB_FILEDOWNLOAD;
|
extern std::string WEB_FILEDOWNLOAD;
|
||||||
extern std::string G_CONNECT_TOPIC;
|
extern std::string G_CONNECT_TOPIC;
|
||||||
|
|
||||||
|
extern int RECALL_ONLY_FLAG;
|
||||||
|
|
||||||
|
//lnk20250115添加台账锁
|
||||||
|
extern pthread_mutex_t mtx;
|
||||||
|
|
||||||
bool DEBUGOPEN = 0;
|
bool DEBUGOPEN = 0;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -56,7 +73,10 @@ public:
|
|||||||
int nDataType; //告警SOE事件类型
|
int nDataType; //告警SOE事件类型
|
||||||
QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
||||||
QString triggerFlag; //告警SOE事件触发指标名称
|
QString triggerFlag; //告警SOE事件触发指标名称
|
||||||
int nIndex; //数据在每条线路LineInfo值数组中的位置
|
int nIndex; //数据在每条线路LineInfo值数组中的位置
|
||||||
|
|
||||||
|
QString desc; //soe事件描述
|
||||||
|
|
||||||
QString DO; //数据对象名
|
QString DO; //数据对象名
|
||||||
QString DA; //数据属性名
|
QString DA; //数据属性名
|
||||||
QString strFullName; //数据对象名 $ 数据属性名
|
QString strFullName; //数据对象名 $ 数据属性名
|
||||||
@@ -145,7 +165,9 @@ public:
|
|||||||
QString WavePhasicA;
|
QString WavePhasicA;
|
||||||
QString WavePhasicB;
|
QString WavePhasicB;
|
||||||
QString WavePhasicC;
|
QString WavePhasicC;
|
||||||
QString UnitOfTimeUnit; //暂态事件持续事件单位:0 - 毫秒 1 - 秒
|
QString TypeOfData; //闪变和统计是否合并 0-分开 1-合并
|
||||||
|
QString IEDControl; //例:LD0 lnk2026-5-13
|
||||||
|
QString UnitOfTimeUnit; //暂态事件持续事件单位:0 - 毫秒 1 - 秒 lnk20260127
|
||||||
QString ValueOfTimeUnit; //上送值的时间:UTC-UTC时间 beijing-北京时间
|
QString ValueOfTimeUnit; //上送值的时间:UTC-UTC时间 beijing-北京时间
|
||||||
QString WaveTimeFlag; //录波文件的时间:UTC-UTC时间 beijing-北京时间
|
QString WaveTimeFlag; //录波文件的时间:UTC-UTC时间 beijing-北京时间
|
||||||
QString IEDname; //例:PQMonitor
|
QString IEDname; //例:PQMonitor
|
||||||
@@ -223,7 +245,106 @@ extern int isdelta_flag;//lnk2024-8-16 角型接线标志
|
|||||||
void connectlog_pgsql(char* id,char* datetime,int status);
|
void connectlog_pgsql(char* id,char* datetime,int status);
|
||||||
///////////////////////////////////////////////lnk20241021替换web接口//////////////////////////////////
|
///////////////////////////////////////////////lnk20241021替换web接口//////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////lnk20260305数据追踪
|
||||||
|
static QString escape_json_string(const QString& s)
|
||||||
|
{
|
||||||
|
QString out = s;
|
||||||
|
out.replace("\\", "\\\\");
|
||||||
|
out.replace("\"", "\\\"");
|
||||||
|
out.replace("\r", "\\r");
|
||||||
|
out.replace("\n", "\\n");
|
||||||
|
out.replace("\t", "\\t");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开追踪:次数 times(比如 5)
|
||||||
|
void process_trace_command(const std::string& id, int times)
|
||||||
|
{
|
||||||
|
if (times <= 0) return;
|
||||||
|
QString qid = QString::fromStdString(id).trimmed();
|
||||||
|
if (qid.isEmpty()) return;
|
||||||
|
|
||||||
|
QMutexLocker lk(&g_trace_mutex);
|
||||||
|
g_trace_map[qid] = times; // 重新打开就覆盖/重置次数
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询是否要追踪
|
||||||
|
static bool trace_is_enabled(const QString& mp_id)
|
||||||
|
{
|
||||||
|
QMutexLocker lk(&g_trace_mutex);
|
||||||
|
auto it = g_trace_map.constFind(mp_id);
|
||||||
|
return (it != g_trace_map.constEnd() && it.value() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命中一次并扣减;扣到 0 自动删
|
||||||
|
static void trace_hit_and_decrement(const QString& mp_id)
|
||||||
|
{
|
||||||
|
QMutexLocker lk(&g_trace_mutex);
|
||||||
|
auto it = g_trace_map.find(mp_id);
|
||||||
|
if (it == g_trace_map.end()) return;
|
||||||
|
|
||||||
|
int left = it.value();
|
||||||
|
left -= 1;
|
||||||
|
if (left <= 0) g_trace_map.erase(it);
|
||||||
|
else it.value() = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
//追踪61850原始数据
|
||||||
|
static QString build_mms_multiline_text(const json_block_data* data)
|
||||||
|
{
|
||||||
|
QStringList lines;
|
||||||
|
|
||||||
|
QMapIterator<QString, double> it(data->mms_str_map);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
lines << QString("%1 = %2").arg(it.key()).arg(it.value(), 0, 'g', 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString build_trace_json(const json_block_data* data)
|
||||||
|
{
|
||||||
|
if (!data) return "{}";
|
||||||
|
|
||||||
|
QString mms_text = build_mms_multiline_text(data);
|
||||||
|
|
||||||
|
QString json;
|
||||||
|
json += "{";
|
||||||
|
json += QString("\"mp_id\":\"%1\",").arg(escape_json_string(data->mp_id));
|
||||||
|
json += QString("\"func_type\":%1,").arg(data->func_type);
|
||||||
|
json += QString("\"data_time\":%1,").arg(QString::number((qlonglong)data->time));
|
||||||
|
json += QString("\"voltage_level\":\"%1\",").arg(QString::number(data->voltage_level, 'f', 6));
|
||||||
|
json += QString("\"dev_type\":\"%1\",").arg(escape_json_string(data->dev_type));
|
||||||
|
json += QString("\"mms_text\":\"%1\"").arg(escape_json_string(mms_text));
|
||||||
|
json += "}";
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_trace_if_needed(json_block_data* pdata)
|
||||||
|
{
|
||||||
|
const QString mp_id_q = pdata->mp_id;
|
||||||
|
if (trace_is_enabled(mp_id_q)) {
|
||||||
|
|
||||||
|
// 1) 组 json
|
||||||
|
QString jsonText = build_trace_json(pdata);
|
||||||
|
|
||||||
|
// 2) 组 KafkaData
|
||||||
|
Ckafka_data_t KafkaData;
|
||||||
|
KafkaData.monitor_id = pdata->monitorId;
|
||||||
|
KafkaData.mp_id = pdata->mp_id;
|
||||||
|
KafkaData.strTopic = "DATA_TRACE_TOPIC";
|
||||||
|
KafkaData.strText = jsonText;
|
||||||
|
|
||||||
|
kafka_data_list_mutex.lock();
|
||||||
|
kafka_data_list.append(KafkaData);
|
||||||
|
kafka_data_list_mutex.unlock();
|
||||||
|
|
||||||
|
// 3) 次数 -1
|
||||||
|
trace_hit_and_decrement(mp_id_q);
|
||||||
|
}
|
||||||
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////lnk20250710添加频率值存储
|
////////////////////////////////////////////////////////////////////////////////////////////lnk20250710添加频率值存储
|
||||||
struct mp_freq_save {
|
struct mp_freq_save {
|
||||||
double G_FREQ;
|
double G_FREQ;
|
||||||
@@ -244,6 +365,8 @@ bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(out_cfg, 0, sizeof(*out_cfg));
|
||||||
|
|
||||||
QString dev_type_q = QString::fromUtf8(dev_type);
|
QString dev_type_q = QString::fromUtf8(dev_type);
|
||||||
QMap<QString, Xmldata*>::iterator it = xmlinfo_list.find(dev_type_q);
|
QMap<QString, Xmldata*>::iterator it = xmlinfo_list.find(dev_type_q);
|
||||||
if (it == xmlinfo_list.end() || it.value() == nullptr) {
|
if (it == xmlinfo_list.end() || it.value() == nullptr) {
|
||||||
@@ -259,8 +382,10 @@ bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg) {
|
|||||||
strncpy(out_cfg->WavePhasicB, cfg.WavePhasicB.toUtf8().constData(), sizeof(out_cfg->WavePhasicB) - 1);
|
strncpy(out_cfg->WavePhasicB, cfg.WavePhasicB.toUtf8().constData(), sizeof(out_cfg->WavePhasicB) - 1);
|
||||||
strncpy(out_cfg->WavePhasicC, cfg.WavePhasicC.toUtf8().constData(), sizeof(out_cfg->WavePhasicC) - 1);
|
strncpy(out_cfg->WavePhasicC, cfg.WavePhasicC.toUtf8().constData(), sizeof(out_cfg->WavePhasicC) - 1);
|
||||||
strncpy(out_cfg->UnitOfTimeUnit, cfg.UnitOfTimeUnit.toUtf8().constData(), sizeof(out_cfg->UnitOfTimeUnit) - 1);
|
strncpy(out_cfg->UnitOfTimeUnit, cfg.UnitOfTimeUnit.toUtf8().constData(), sizeof(out_cfg->UnitOfTimeUnit) - 1);
|
||||||
|
strncpy(out_cfg->TypeOfData, cfg.TypeOfData.toUtf8().constData(), sizeof(out_cfg->TypeOfData) - 1); out_cfg->TypeOfData[sizeof(out_cfg->TypeOfData) - 1] = '\0';//lnk20260127
|
||||||
strncpy(out_cfg->ValueOfTimeUnit, cfg.ValueOfTimeUnit.toUtf8().constData(),sizeof(out_cfg->ValueOfTimeUnit) - 1);
|
strncpy(out_cfg->ValueOfTimeUnit, cfg.ValueOfTimeUnit.toUtf8().constData(),sizeof(out_cfg->ValueOfTimeUnit) - 1);
|
||||||
strncpy(out_cfg->WaveTimeFlag, cfg.WaveTimeFlag.toUtf8().constData(), sizeof(out_cfg->WaveTimeFlag) - 1);
|
strncpy(out_cfg->WaveTimeFlag, cfg.WaveTimeFlag.toUtf8().constData(), sizeof(out_cfg->WaveTimeFlag) - 1);
|
||||||
|
strncpy(out_cfg->IEDControl, cfg.IEDControl.toUtf8().constData(), sizeof(out_cfg->IEDControl) - 1);//lnk2026-5-13
|
||||||
strncpy(out_cfg->IEDname, cfg.IEDname.toUtf8().constData(), sizeof(out_cfg->IEDname) - 1);
|
strncpy(out_cfg->IEDname, cfg.IEDname.toUtf8().constData(), sizeof(out_cfg->IEDname) - 1);
|
||||||
strncpy(out_cfg->LDevicePrefix, cfg.LDevicePrefix.toUtf8().constData(), sizeof(out_cfg->LDevicePrefix) - 1);
|
strncpy(out_cfg->LDevicePrefix, cfg.LDevicePrefix.toUtf8().constData(), sizeof(out_cfg->LDevicePrefix) - 1);
|
||||||
|
|
||||||
@@ -620,9 +745,9 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号
|
dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号
|
||||||
dv1->DO = e_Value.attribute("DO"); //数据对象名
|
dv1->DO = e_Value.attribute("DO"); //数据对象名
|
||||||
|
|
||||||
std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
||||||
std::cout << dv1->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
|
if(DEBUGOPEN)std::cout << dv1->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
|
||||||
std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
||||||
|
|
||||||
dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //将数据名中%0,49%替换为具体数字 例:SI_%0,49%变为SI_1
|
dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //将数据名中%0,49%替换为具体数字 例:SI_%0,49%变为SI_1
|
||||||
dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //将DA中%-2替换为具体数字 例:phs*Har[1]$mag$f
|
dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //将DA中%-2替换为具体数字 例:phs*Har[1]$mag$f
|
||||||
@@ -679,9 +804,9 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
dv2->DO = e_Value.attribute("DO"); //数据对象名
|
dv2->DO = e_Value.attribute("DO"); //数据对象名
|
||||||
dv2->DA = strDAName; //数据属性名
|
dv2->DA = strDAName; //数据属性名
|
||||||
|
|
||||||
std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
||||||
std::cout << dv2->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
|
if(DEBUGOPEN)std::cout << dv2->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
|
||||||
std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
|
||||||
|
|
||||||
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
|
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
|
||||||
if (e_Value.attributes().contains("BaseFlag"))
|
if (e_Value.attributes().contains("BaseFlag"))
|
||||||
@@ -865,6 +990,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
{
|
{
|
||||||
CEventData* ed = new CEventData(); //SOE事件类指针
|
CEventData* ed = new CEventData(); //SOE事件类指针
|
||||||
ed->triggerFlag = node.toElement().attribute("name"); //SOE名称
|
ed->triggerFlag = node.toElement().attribute("name"); //SOE名称
|
||||||
|
ed->desc = node.toElement().attribute("desc"); //SOE描述
|
||||||
ed->DO = node.toElement().attribute("DO"); //数据对象名
|
ed->DO = node.toElement().attribute("DO"); //数据对象名
|
||||||
ed->DA = node.toElement().attribute("DA"); //数据属性名
|
ed->DA = node.toElement().attribute("DA"); //数据属性名
|
||||||
ed->type = node.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
ed->type = node.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
||||||
@@ -898,6 +1024,11 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
{
|
{
|
||||||
cfg->UnitOfTimeUnit.append(e.attribute("Unit"));
|
cfg->UnitOfTimeUnit.append(e.attribute("Unit"));
|
||||||
}
|
}
|
||||||
|
//lnk 20260127
|
||||||
|
if ("TypeOfData" == strTag)
|
||||||
|
{
|
||||||
|
cfg->TypeOfData.append(e.attribute("Unit"));
|
||||||
|
}
|
||||||
if ("ValueOfTime" == strTag)
|
if ("ValueOfTime" == strTag)
|
||||||
{
|
{
|
||||||
cfg->ValueOfTimeUnit.append(e.attribute("Unit"));
|
cfg->ValueOfTimeUnit.append(e.attribute("Unit"));
|
||||||
@@ -907,6 +1038,10 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag"));
|
cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if ("IEDControl" == strTag)
|
||||||
|
{
|
||||||
|
cfg->IEDControl.append(e.attribute("name"));
|
||||||
|
}
|
||||||
if ("IED" == strTag)
|
if ("IED" == strTag)
|
||||||
{
|
{
|
||||||
cfg->IEDname.append(e.attribute("name"));
|
cfg->IEDname.append(e.attribute("name"));
|
||||||
@@ -1029,9 +1164,46 @@ void printCTopicList(const std::list<CTopic*>& ctopic_list) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== DEBUG 打印: mms_str_map (属性名 -> 值) =====
|
||||||
|
static void print_mms_str_map(const json_block_data* data)
|
||||||
|
{
|
||||||
|
if (!data) {
|
||||||
|
std::cout << "[DBG] json_block_data is NULL\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n========== [DBG] json_block_data.mms_str_map ==========\n";
|
||||||
|
std::cout << "[DBG] monitorId=" << data->monitorId
|
||||||
|
<< " func_type=" << data->func_type
|
||||||
|
<< " flag=" << data->flag
|
||||||
|
<< " time(ms)=" << data->time
|
||||||
|
<< " voltage_level=" << data->voltage_level
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
std::cout << "[DBG] mp_id=" << data->mp_id.toStdString()
|
||||||
|
<< " dev_type=" << data->dev_type.toStdString()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
std::cout << "[DBG] mms_str_map size=" << data->mms_str_map.size() << "\n";
|
||||||
|
|
||||||
|
// Qt4/Qt5 都稳:QMapIterator
|
||||||
|
QMapIterator<QString, double> it(data->mms_str_map);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
std::cout << " " << it.key().toStdString() << " = " << it.value() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "======================================================\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
//20250214添加角型接线处理
|
//20250214添加角型接线处理
|
||||||
int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据
|
int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据
|
||||||
{
|
{
|
||||||
|
// 刚进函数就打印 mms_str_map
|
||||||
|
if (DEBUGOPEN) {
|
||||||
|
print_mms_str_map(data);
|
||||||
|
}
|
||||||
|
|
||||||
list<CTopic*> ctopic_list;
|
list<CTopic*> ctopic_list;
|
||||||
|
|
||||||
////lnk2024-8-15 区分星型,角型接线
|
////lnk2024-8-15 区分星型,角型接线
|
||||||
@@ -1054,7 +1226,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
cout << "transfer_json_block_data contain data->dev_type" << endl;
|
cout << "transfer_json_block_data contain data->dev_type" << endl;
|
||||||
ctopic_list = xmlinfo_list2[data->dev_type]->topicList;
|
ctopic_list = xmlinfo_list2[data->dev_type]->topicList;
|
||||||
|
|
||||||
if(DEBUGOPEN)printCTopicList(ctopic_list);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl;
|
cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl;
|
||||||
@@ -1063,6 +1235,44 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(DEBUGOPEN)printCTopicList(ctopic_list);
|
||||||
|
|
||||||
|
//lnk20260127 添加数据类型区分
|
||||||
|
bool typeofdata = false;
|
||||||
|
bool data_have_static = data->data_have_statistic;
|
||||||
|
|
||||||
|
QString devType = data->dev_type;
|
||||||
|
QByteArray devTypeBytes = devType.toUtf8();
|
||||||
|
const char* dev_type_cstr = devTypeBytes.constData();
|
||||||
|
qDebug() << "[DBG] devType (QString) =" << devType;
|
||||||
|
qDebug() << "[DBG] devType length =" << devType.length();
|
||||||
|
qDebug() << "[DBG] devTypeBytes =" << devTypeBytes;
|
||||||
|
qDebug() << "[DBG] devTypeBytes size =" << devTypeBytes.size();
|
||||||
|
|
||||||
|
printf("[DBG] dev_type_cstr = '%s'\n", dev_type_cstr);
|
||||||
|
XmlConfigC cfg1;
|
||||||
|
if (get_xml_config_by_dev_type(dev_type_cstr, &cfg1)) {
|
||||||
|
printf("========== XmlConfigC dump ==========\n");
|
||||||
|
printf("WavePhasicFlag = '%s'\n", cfg1.WavePhasicFlag);
|
||||||
|
printf("WavePhasicA = '%s'\n", cfg1.WavePhasicA);
|
||||||
|
printf("WavePhasicB = '%s'\n", cfg1.WavePhasicB);
|
||||||
|
printf("WavePhasicC = '%s'\n", cfg1.WavePhasicC);
|
||||||
|
printf("UnitOfTimeUnit = '%s'\n", cfg1.UnitOfTimeUnit);
|
||||||
|
printf("TypeOfData = '%s'\n", cfg1.TypeOfData);
|
||||||
|
printf("ValueOfTimeUnit = '%s'\n", cfg1.ValueOfTimeUnit);
|
||||||
|
printf("WaveTimeFlag = '%s'\n", cfg1.WaveTimeFlag);
|
||||||
|
printf("IEDControl = '%s'\n", cfg1.IEDControl);
|
||||||
|
printf("IEDname = '%s'\n", cfg1.IEDname);
|
||||||
|
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
|
||||||
|
printf("=====================================\n");
|
||||||
|
// 如果 TypeOfData == "1",则置 true
|
||||||
|
if (strcmp(cfg1.TypeOfData, "1") == 0) {
|
||||||
|
typeofdata = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("not find this dev_type\n");
|
||||||
|
}
|
||||||
|
|
||||||
bool shortjumpflag = false;
|
bool shortjumpflag = false;
|
||||||
bool longjumpflag = false;
|
bool longjumpflag = false;
|
||||||
|
|
||||||
@@ -1336,11 +1546,16 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
kafka_data_list_mutex.unlock(); //解锁
|
kafka_data_list_mutex.unlock(); //解锁
|
||||||
longjumpflag = true;
|
longjumpflag = true;
|
||||||
}
|
}
|
||||||
if (longjumpflag == true || shortjumpflag == true) {
|
|
||||||
return 1;
|
//lnk20260127
|
||||||
}
|
if (typeofdata == false || data_have_static == false) {//不合并则处理完闪变就不处理其他数据,如果有统计数据或者数据类型区分了就继续处理其他数据
|
||||||
|
if (longjumpflag == true || shortjumpflag == true) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} //②-②历史闪变数据解析结束!--------------------------------
|
} //②-②历史闪变数据解析结束!--------------------------------
|
||||||
|
|
||||||
|
//合并则继续处理其他数据
|
||||||
if (1 == pDataType->iDataType) //②-①历史稳态数据-----------------------------------------------------------
|
if (1 == pDataType->iDataType) //②-①历史稳态数据-----------------------------------------------------------
|
||||||
{
|
{
|
||||||
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
|
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
|
||||||
@@ -1710,6 +1925,13 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
while (it != pMonitor->ItemList.end())
|
while (it != pMonitor->ItemList.end())
|
||||||
{
|
{
|
||||||
CItem* pItem = *it++;
|
CItem* pItem = *it++;
|
||||||
|
//////////////////////////////////////////////////////////lnk20250306为了数据入库,构造数据添加FLAG
|
||||||
|
if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
|
{
|
||||||
|
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
{
|
{
|
||||||
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
||||||
@@ -2011,6 +2233,13 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
while (it != pMonitor->ItemList.end())
|
while (it != pMonitor->ItemList.end())
|
||||||
{
|
{
|
||||||
CItem* pItem = *it++;
|
CItem* pItem = *it++;
|
||||||
|
//////////////////////////////////////////////////////////lnk20250306为了数据入库,构造数据添加FLAG
|
||||||
|
if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
|
{
|
||||||
|
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
{
|
{
|
||||||
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
||||||
@@ -2128,6 +2357,13 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
while (it != pMonitor->ItemList.end())
|
while (it != pMonitor->ItemList.end())
|
||||||
{
|
{
|
||||||
CItem* pItem = *it++;
|
CItem* pItem = *it++;
|
||||||
|
//////////////////////////////////////////////////////////lnk20250306为了数据入库,构造数据添加FLAG
|
||||||
|
if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
|
{
|
||||||
|
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针
|
||||||
{
|
{
|
||||||
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒
|
||||||
@@ -2219,8 +2455,10 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
kafka_data_list_mutex.unlock(); //解锁
|
kafka_data_list_mutex.unlock(); //解锁
|
||||||
longjumpflag = true;
|
longjumpflag = true;
|
||||||
}
|
}
|
||||||
if (longjumpflag == true || shortjumpflag == true) {
|
if (typeofdata == false || data_have_static == false) {//不合并则处理完闪变就不处理其他数据
|
||||||
return 1;
|
if (longjumpflag == true || shortjumpflag == true) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//return 1; //结束该函数,停止后续代码执行
|
//return 1; //结束该函数,停止后续代码执行
|
||||||
} //②-②历史闪变数据解析结束!--------------------------------
|
} //②-②历史闪变数据解析结束!--------------------------------
|
||||||
@@ -2540,8 +2778,28 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void format_time_ms(long long ms, char* buf, size_t buf_len)
|
||||||
|
{
|
||||||
|
time_t sec = ms / 1000;
|
||||||
|
int milli = ms % 1000;
|
||||||
|
|
||||||
|
struct tm tm_time;
|
||||||
|
localtime_r(&sec, &tm_time); // 线程安全
|
||||||
|
|
||||||
|
snprintf(buf, buf_len,
|
||||||
|
"%04d-%02d-%02d %02d:%02d:%02d.%03d",
|
||||||
|
tm_time.tm_year + 1900,
|
||||||
|
tm_time.tm_mon + 1,
|
||||||
|
tm_time.tm_mday,
|
||||||
|
tm_time.tm_hour,
|
||||||
|
tm_time.tm_min,
|
||||||
|
tm_time.tm_sec,
|
||||||
|
milli);
|
||||||
|
}
|
||||||
|
|
||||||
void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long time,char* devtype,int monitor_id)
|
void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long time,char* devtype,int monitor_id)
|
||||||
{
|
{
|
||||||
|
|
||||||
XmlConfig c_xmlcfg;
|
XmlConfig c_xmlcfg;
|
||||||
if (xmlinfo_list.contains(devtype)) {
|
if (xmlinfo_list.contains(devtype)) {
|
||||||
c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;
|
c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;
|
||||||
@@ -2573,6 +2831,28 @@ void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long ti
|
|||||||
if (pEventData->strFullName.indexOf(Full_name) != -1)
|
if (pEventData->strFullName.indexOf(Full_name) != -1)
|
||||||
{
|
{
|
||||||
KafkaData.strText.append(QString("\"%1\"").arg(pEventData->triggerFlag));
|
KafkaData.strText.append(QString("\"%1\"").arg(pEventData->triggerFlag));
|
||||||
|
|
||||||
|
//使用日志接口记录日志
|
||||||
|
char time_str[64];
|
||||||
|
format_time_ms(time, time_str, sizeof(time_str));
|
||||||
|
|
||||||
|
QByteArray descBa = pEventData->desc.toLocal8Bit();
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mtx); std::cout << "ggio hold lock !!!!!!!!!!!" << std::endl;
|
||||||
|
const char* mp_name_raw = find_mp_name_from_mp_id(mp_id);
|
||||||
|
pthread_mutex_unlock(&mtx); std::cout << "ggio unlock lock !!!!!!!!!!!" << std::endl;
|
||||||
|
|
||||||
|
char mp_name[128];
|
||||||
|
if (mp_name_raw && mp_name_raw[0] != '\0') {
|
||||||
|
snprintf(mp_name, sizeof(mp_name), "%s", mp_name_raw);
|
||||||
|
} else {
|
||||||
|
snprintf(mp_name, sizeof(mp_name), "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
DIY_WARNLOG_CODE(mp_id,2 ,LOG_CODE_GGIO_LPHD,
|
||||||
|
"监测点:%s(%s),在%s发生事件:%s,事件值:%.2f",
|
||||||
|
mp_name, mp_id, time_str, descBa.constData(), v);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2585,6 +2865,7 @@ void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long ti
|
|||||||
kafka_data_list_mutex.lock(); //加锁
|
kafka_data_list_mutex.lock(); //加锁
|
||||||
kafka_data_list.append(KafkaData); //添加 kafka发送链表
|
kafka_data_list.append(KafkaData); //添加 kafka发送链表
|
||||||
kafka_data_list_mutex.unlock(); //解锁
|
kafka_data_list_mutex.unlock(); //解锁
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//zw修改 2023-8-31 新增或更新list队列 写入xml数据库信息 模型编码 终端型号 终端厂家 oss存储路径 时间
|
//zw修改 2023-8-31 新增或更新list队列 写入xml数据库信息 模型编码 终端型号 终端厂家 oss存储路径 时间
|
||||||
@@ -2612,6 +2893,7 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char
|
|||||||
Xmldata* config = new Xmldata(); //没找到就插个新的终端类型到列表中
|
Xmldata* config = new Xmldata(); //没找到就插个新的终端类型到列表中
|
||||||
xmlinfo_list.insert(type, config);
|
xmlinfo_list.insert(type, config);
|
||||||
|
|
||||||
|
xmlinfo_list[type]->updataflag = true;//lnk20250820
|
||||||
//调试用lnk20241125
|
//调试用lnk20241125
|
||||||
cout << "xmlinfo_list insert type:" << type.toStdString() << endl;
|
cout << "xmlinfo_list insert type:" << type.toStdString() << endl;
|
||||||
}
|
}
|
||||||
@@ -2651,6 +2933,7 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char
|
|||||||
{
|
{
|
||||||
Xmldata* config2 = new Xmldata();
|
Xmldata* config2 = new Xmldata();
|
||||||
xmlinfo_list2.insert(type, config2);
|
xmlinfo_list2.insert(type, config2);
|
||||||
|
xmlinfo_list2[type]->updataflag = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2672,37 +2955,50 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char
|
|||||||
|
|
||||||
char file_name[256];
|
char file_name[256];
|
||||||
memset(file_name, 0, 256);
|
memset(file_name, 0, 256);
|
||||||
sprintf(file_name, "%s", FILE_NAME);
|
snprintf(file_name, sizeof(file_name), "%s", FILE_NAME);
|
||||||
|
file_name[sizeof(file_name) - 1] = '\0';
|
||||||
QString Qsavename;
|
QString Qsavename;
|
||||||
Qsavename.append("/FeProject/dat/").append(id).append(".xml"); //本地保存路径
|
Qsavename.append("/FeProject/dat/").append(id).append(".xml"); //本地保存路径
|
||||||
char save_name[256];
|
char save_name[256];
|
||||||
memset(save_name, 0, 256);
|
memset(save_name, 0, 256);
|
||||||
sprintf(save_name, "%s", Qsavename.toAscii().data());
|
snprintf(save_name, sizeof(save_name), "%s", Qsavename.toAscii().data());
|
||||||
|
save_name[sizeof(save_name) - 1] = '\0';
|
||||||
cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl;
|
cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl;
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG("process","【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name);
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name);
|
||||||
|
|
||||||
|
|
||||||
//20241028 lnk 替换为文件下载web接口
|
|
||||||
//构造文件下载接口参数
|
|
||||||
//接口示例http://192.168.1.125:10215/file/download?filePath=/path/xxx.txt
|
|
||||||
// 调用web获取文件内容
|
// 调用web获取文件内容
|
||||||
char* fileContent = NULL;
|
char* fileContent = NULL;
|
||||||
|
|
||||||
//测试下载
|
|
||||||
//char downpath[128] = {"/home/pq/FeProject/src/pt61850netd_pqfe_lnk/download/123.txt"};
|
|
||||||
//char download[128] = {"{\"filename\":\"file_test.txt\"}"};
|
|
||||||
//SendJsonAPI_web("http://192.168.1.149:8091/file/download", "", download, &fileContent);
|
|
||||||
|
|
||||||
std::string fullPath = std::string("filePath=") + std::string(FILE_PATH);
|
std::string fullPath = std::string("filePath=") + std::string(FILE_PATH);
|
||||||
|
|
||||||
//调试用
|
//调试用
|
||||||
std::cout << "fullpath" << fullPath << std::endl;
|
std::cout << "fullpath" << fullPath << std::endl;
|
||||||
|
|
||||||
SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", &fileContent);
|
SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", &fileContent);
|
||||||
if (fileContent != NULL) {
|
if (fileContent != NULL && fileContent[0] != '\0') {
|
||||||
// 创建并打开文件
|
// 创建并打开文件
|
||||||
|
|
||||||
|
//判断返回的是不是错误json响应
|
||||||
|
bool isErrorJson = false;
|
||||||
|
cJSON* root = cJSON_Parse(fileContent);
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON* codeItem = cJSON_GetObjectItem(root, "code");
|
||||||
|
cJSON* dataItem = cJSON_GetObjectItem(root, "data");
|
||||||
|
if (codeItem && codeItem->valuestring &&
|
||||||
|
strcmp(codeItem->valuestring, "A00555") == 0 &&
|
||||||
|
(dataItem == NULL || (dataItem->type == cJSON_NULL))) {
|
||||||
|
isErrorJson = true;
|
||||||
|
std::cerr << "Error: Server returned empty file stream, code=A00555." << std::endl;
|
||||||
|
DIY_ERRORLOG_CODE("process",0, LOG_CODE_ICD_AND_DOWNLOAD,
|
||||||
|
"【ERROR】前置下载文件失败,服务端返回A00555(文件流为空),文件=%s",
|
||||||
|
save_name);
|
||||||
|
}
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
|
||||||
//测试
|
//测试
|
||||||
//std::ofstream outFile(downpath, std::ios::binary);//二进制的方式打开
|
//std::ofstream outFile(downpath, std::ios::binary);//二进制的方式打开
|
||||||
|
|
||||||
@@ -2713,17 +3009,17 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char
|
|||||||
outFile.close();
|
outFile.close();
|
||||||
std::cout << "File saved successfully!" << std::endl;
|
std::cout << "File saved successfully!" << std::endl;
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG("process","【WARN】前置下载映射文件%s成功",save_name);
|
DIY_INFOLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【NORMAL】前置下载映射文件%s成功",save_name);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Error: Unable to open file for writing." << std::endl;
|
std::cerr << "Error: Unable to open file for writing." << std::endl;
|
||||||
DIY_ERRORLOG("process","【ERROR】前置写入本地映射文件%s失败",save_name);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置写入本地映射文件%s失败",save_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放分配的内存
|
// 释放分配的内存
|
||||||
free(fileContent);
|
free(fileContent);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Error: Unable to download file." << std::endl;
|
std::cerr << "Error: Unable to download file." << std::endl;
|
||||||
DIY_ERRORLOG("process","【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2984,14 +3280,13 @@ void connectlog_pgsql(char* id,char* datetime,int status)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//使用mq
|
//使用mq
|
||||||
Ckafka_data_t connect_info;
|
Ckafka_data_t connect_info;
|
||||||
connect_info.strTopic = QString::fromStdString(G_CONNECT_TOPIC);
|
connect_info.strTopic = QString::fromStdString(G_CONNECT_TOPIC);
|
||||||
|
connect_info.mp_id = QString::fromLocal8Bit(id);//这里填装置id,后续作为key
|
||||||
connect_info.strText = QString::fromStdString(std::string(jsonString));
|
connect_info.strText = QString::fromStdString(std::string(jsonString));
|
||||||
|
|
||||||
if(g_node_id == STAT_DATA_BASE_NODE_ID){//稳态才上传
|
if((g_node_id == STAT_DATA_BASE_NODE_ID && RECALL_ONLY_FLAG == 0) || (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID && RECALL_ONLY_FLAG == 1)){//稳态或者补招才上传
|
||||||
kafka_data_list_mutex.lock(); //加锁
|
kafka_data_list_mutex.lock(); //加锁
|
||||||
kafka_data_list.append(connect_info); //添加 kafka发送链表
|
kafka_data_list.append(connect_info); //添加 kafka发送链表
|
||||||
kafka_data_list_mutex.unlock(); //解锁
|
kafka_data_list_mutex.unlock(); //解锁
|
||||||
@@ -3050,16 +3345,17 @@ static void getDirectoryFilesInfo(const std::string &dirPath, std::vector<FileIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 将 JSON 字符串写入指定文件
|
// 将 JSON 字符串写入指定文件
|
||||||
static void writeJsonToFile(const char* filePath, const char* jsonString)
|
static bool writeJsonToFile(const char* filePath, const char* jsonString)
|
||||||
{
|
{
|
||||||
FILE* fp = fopen(filePath, "w");
|
FILE* fp = fopen(filePath, "w");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
DIY_ERRORLOG("process","【ERROR】无法将暂态事件写入本地缓存");
|
//DIY_ERRORLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM,"【ERROR】无法将暂态事件写入本地缓存");
|
||||||
std::cerr << "Failed to write in file : " << filePath << std::endl;
|
std::cerr << "Failed to write in file : " << filePath << std::endl;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
fprintf(fp, "%s", jsonString);
|
fprintf(fp, "%s", jsonString);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查 qvvr 目录下文件总大小,若超过 10M 则删除最老的一个文件
|
// 检查 qvvr 目录下文件总大小,若超过 10M 则删除最老的一个文件
|
||||||
@@ -3140,7 +3436,7 @@ static void scanAndResendOfflineFiles(const std::string &dirPath)
|
|||||||
// 读取文件内容(即之前存的 JSON)
|
// 读取文件内容(即之前存的 JSON)
|
||||||
FILE* fp = fopen(fileList[i].fileName.c_str(), "r");
|
FILE* fp = fopen(fileList[i].fileName.c_str(), "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
DIY_ERRORLOG("process","【ERROR】无法打开本地缓存的暂态事件");
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM,"【ERROR】无法打开本地缓存的暂态事件");
|
||||||
std::cerr << " fail to open exsist file " << fileList[i].fileName << std::endl;
|
std::cerr << " fail to open exsist file " << fileList[i].fileName << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3160,26 +3456,27 @@ static void scanAndResendOfflineFiles(const std::string &dirPath)
|
|||||||
// 尝试发送
|
// 尝试发送
|
||||||
char* ptr = NULL; // 接收返回
|
char* ptr = NULL; // 接收返回
|
||||||
SendJsonAPI_web(WEB_EVENT, "", jsonContent.c_str(), &ptr);
|
SendJsonAPI_web(WEB_EVENT, "", jsonContent.c_str(), &ptr);
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL && ptr[0] != '\0') {
|
||||||
|
|
||||||
cJSON* j_r = cJSON_Parse(ptr);
|
cJSON* j_r = cJSON_Parse(ptr);
|
||||||
if (j_r == NULL) {
|
if (j_r == NULL) {
|
||||||
std::cout << "old file send fail" << std::endl;
|
std::cout << "old file send fail" << std::endl;
|
||||||
// 表示有响应,则可视为成功;根据项目需要可加更精细的判断
|
|
||||||
handleCommentResponse(std::string(ptr));
|
|
||||||
|
|
||||||
DIY_WARNLOG("process","【WARN】前置重发暂态事件失败");
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件失败");
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
// 表示有响应,则可视为成功;根据项目需要可加更精细的判断
|
||||||
|
handleCommentResponse(std::string(ptr));
|
||||||
|
|
||||||
DIY_WARNLOG("process","【WARN】前置重发暂态事件成功");
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件成功");
|
||||||
|
|
||||||
std::cout << "old file send success,remove it" << std::endl;
|
std::cout << "old file send success,remove it" << std::endl;
|
||||||
// 删除文件
|
// 删除文件
|
||||||
remove(fileList[i].fileName.c_str());
|
remove(fileList[i].fileName.c_str());
|
||||||
|
|
||||||
free(j_r);
|
cJSON_Delete(j_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3208,13 +3505,6 @@ char* uuid_cfg,char* uuid_dat,
|
|||||||
char* mp_id,char* Qvvr_rptname,char* devtype)
|
char* mp_id,char* Qvvr_rptname,char* devtype)
|
||||||
{
|
{
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
// 原本的逻辑,不做任何改动
|
// 原本的逻辑,不做任何改动
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
XmlConfig c_xmlcfg;
|
XmlConfig c_xmlcfg;
|
||||||
@@ -3225,7 +3515,7 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
c_xmlcfg = xmlcfg;
|
c_xmlcfg = xmlcfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(mp_id) == 0) {
|
if (NULL == mp_id || strlen(mp_id) == 0 ) {
|
||||||
std::cout << "mp_id is null" << std::endl;
|
std::cout << "mp_id is null" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3268,6 +3558,12 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* json_string = cJSON_Print(root);
|
char* json_string = cJSON_Print(root);
|
||||||
|
if (json_string == NULL) {
|
||||||
|
DIY_ERRORLOG_CODE(mp_id,2,LOG_CODE_TRANSIENT_COMM,"【ERROR】监测点:%s暂态事件生成JSON字符串失败",mp_id);
|
||||||
|
std::cerr << "Failed to print JSON object." << std::endl;
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
printf("%s\n", json_string); // 输出 JSON 字符串
|
printf("%s\n", json_string); // 输出 JSON 字符串
|
||||||
|
|
||||||
// 发送到暂态接口
|
// 发送到暂态接口
|
||||||
@@ -3276,14 +3572,14 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
|
|
||||||
// ================ 插入新功能 =========================
|
// ================ 插入新功能 =========================
|
||||||
// ********** 新增功能开始 **********
|
// ********** 新增功能开始 **********
|
||||||
if(ptr != NULL)
|
if(ptr != NULL && ptr[0] != '\0')
|
||||||
{
|
{
|
||||||
cJSON* j_r = cJSON_Parse(ptr);
|
cJSON* j_r = cJSON_Parse(ptr);
|
||||||
// 如果发送失败(j_r == NULL),则把当前 json 存入指定目录(/FeProject/dat/qvvr/)
|
// 如果发送失败(j_r == NULL),则把当前 json 存入指定目录(/FeProject/dat/qvvr/)
|
||||||
if (j_r == NULL) {
|
if (j_r == NULL) {
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_ERRORLOG(full_key_m_d,"【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件",mp_id);
|
DIY_ERRORLOG_CODE(mp_id,2,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件",mp_id);
|
||||||
|
|
||||||
std::cout << "qvvr send fail ,store in local" << std::endl;
|
std::cout << "qvvr send fail ,store in local" << std::endl;
|
||||||
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件
|
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件
|
||||||
@@ -3304,12 +3600,14 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
fileName += ".txt";
|
fileName += ".txt";
|
||||||
|
|
||||||
// 把 json_string 写入文件
|
// 把 json_string 写入文件
|
||||||
writeJsonToFile(fileName.c_str(), json_string);
|
if(!writeJsonToFile(fileName.c_str(), json_string)){
|
||||||
|
DIY_ERRORLOG_CODE(mp_id,2,LOG_CODE_TRANSIENT_COMM,"【ERROR】监测点:%s无法将暂态时间为%lld的暂态事件写入本地缓存",mp_id,start_tm);
|
||||||
|
}
|
||||||
|
|
||||||
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
|
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
free(j_r);
|
cJSON_Delete(j_r);
|
||||||
//后续处理
|
//后续处理
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3322,16 +3620,17 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
// ********** 新增功能结束 **********
|
// ********** 新增功能结束 **********
|
||||||
|
|
||||||
// 下面继续原逻辑,不动,处理本次发送
|
// 下面继续原逻辑,不动,处理本次发送
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL && ptr[0] != '\0') {
|
||||||
std::cout << "current qvvr handle response" << std::endl;
|
std::cout << "current qvvr handle response" << std::endl;
|
||||||
handleCommentResponse(std::string(ptr));
|
handleCommentResponse(std::string(ptr));
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
ptr = NULL;
|
||||||
} else {
|
} else {
|
||||||
// 处理 ptr 为 NULL 的情况,例如日志记录或错误处理
|
// 处理 ptr 为 NULL 的情况,例如日志记录或错误处理
|
||||||
std::cout << "Error: Received NULL response" << std::endl;
|
std::cout << "Error: Received NULL response" << std::endl;
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_ERRORLOG(full_key_m_d,"【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件",mp_id);
|
DIY_ERRORLOG_CODE(mp_id,2,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件",mp_id);
|
||||||
|
|
||||||
std::cout << "qvvr send fail ,store in local" << std::endl;
|
std::cout << "qvvr send fail ,store in local" << std::endl;
|
||||||
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件
|
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件
|
||||||
@@ -3350,7 +3649,9 @@ char* mp_id,char* Qvvr_rptname,char* devtype)
|
|||||||
fileName += buf;
|
fileName += buf;
|
||||||
fileName += ".txt";
|
fileName += ".txt";
|
||||||
// 把 json_string 写入文件
|
// 把 json_string 写入文件
|
||||||
writeJsonToFile(fileName.c_str(), json_string);
|
if(!writeJsonToFile(fileName.c_str(), json_string)){
|
||||||
|
DIY_ERRORLOG_CODE(mp_id,2,LOG_CODE_TRANSIENT_COMM,"【ERROR】监测点:%s无法将暂态时间为%lld的暂态事件写入本地缓存",mp_id,start_tm);
|
||||||
|
}
|
||||||
|
|
||||||
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
|
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
|
||||||
|
|
||||||
@@ -3403,7 +3704,7 @@ void Set_xml_nodeinfo_one(char* dev_type)
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
|
if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
|
||||||
if(xmlinfo_list[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
|
//if(xmlinfo_list[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
|
||||||
|
|
||||||
//将这个点的xmlcfg和topicList删除
|
//将这个点的xmlcfg和topicList删除
|
||||||
clearXmlConfigAndTopicList(xmlinfo_list[QString::fromUtf8(dev_type)]);
|
clearXmlConfigAndTopicList(xmlinfo_list[QString::fromUtf8(dev_type)]);
|
||||||
@@ -3413,7 +3714,7 @@ void Set_xml_nodeinfo_one(char* dev_type)
|
|||||||
{
|
{
|
||||||
std::cout << "!!!! this ledger xml config fail!!!!" << std::endl;
|
std::cout << "!!!! this ledger xml config fail!!!!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -3422,7 +3723,7 @@ void Set_xml_nodeinfo_one(char* dev_type)
|
|||||||
//添加角形
|
//添加角形
|
||||||
if(isdelta_flag){
|
if(isdelta_flag){
|
||||||
if(xmlinfo_list2[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
|
if(xmlinfo_list2[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
|
||||||
if(xmlinfo_list2[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
|
//if(xmlinfo_list2[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
|
||||||
|
|
||||||
//将这个点的xmlcfg和topicList删除
|
//将这个点的xmlcfg和topicList删除
|
||||||
clearXmlConfigAndTopicList(xmlinfo_list2[QString::fromUtf8(dev_type)]);
|
clearXmlConfigAndTopicList(xmlinfo_list2[QString::fromUtf8(dev_type)]);
|
||||||
@@ -3432,7 +3733,7 @@ void Set_xml_nodeinfo_one(char* dev_type)
|
|||||||
{
|
{
|
||||||
std::cout << "!!!! this ledger xml config fail!!!!" << std::endl;
|
std::cout << "!!!! this ledger xml config fail!!!!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ public:
|
|||||||
QString mp_id; //char型监测点
|
QString mp_id; //char型监测点
|
||||||
QString dev_type;//设备类型
|
QString dev_type;//设备类型
|
||||||
|
|
||||||
|
bool data_have_statistic;//是否有统计数据,0没有,1有
|
||||||
|
|
||||||
QMap<QString, double> mms_str_map; //数据值(61850数据属性名, 数据值)
|
QMap<QString, double> mms_str_map; //数据值(61850数据属性名, 数据值)
|
||||||
|
|
||||||
|
bool data_trace_flag; //数据追踪标记,0不追踪,1追踪
|
||||||
};
|
};
|
||||||
|
|
||||||
class Ckafka_data_t //kafka发送数据结构类
|
class Ckafka_data_t //kafka发送数据结构类
|
||||||
|
|||||||
1452
json/save2json.cpp
1452
json/save2json.cpp
File diff suppressed because it is too large
Load Diff
@@ -670,6 +670,8 @@ struct monitor // 监测点台账
|
|||||||
char timestamp[64];
|
char timestamp[64];
|
||||||
char status[255];
|
char status[255];
|
||||||
|
|
||||||
|
int log_level;//日志级别,0:ERROR,1:WARN,2:NORMAL,3:DEBUG
|
||||||
|
|
||||||
};
|
};
|
||||||
struct terminal // 终端台账
|
struct terminal // 终端台账
|
||||||
{
|
{
|
||||||
@@ -692,6 +694,7 @@ struct terminal // 终端台账
|
|||||||
char timestamp[64];
|
char timestamp[64];
|
||||||
monitor line[10]; // 最多 10 个监测点
|
monitor line[10]; // 最多 10 个监测点
|
||||||
|
|
||||||
|
int log_level;//日志级别,0:ERROR,1:WARN,2:NORMAL,3:DEBUG
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
BIN
librocketmq.a
BIN
librocketmq.a
Binary file not shown.
BIN
librocketmq.so
BIN
librocketmq.so
Binary file not shown.
248
log4cplus/config/defines.hxx
Normal file
248
log4cplus/config/defines.hxx
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
/* include/log4cplus/config/defines.hxx. Generated from defines.hxx.in by configure. */
|
||||||
|
#ifndef LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||||
|
#define LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYSLOG_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_ARPA_INET_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_NETINET_IN_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_NETINET_TCP_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_TIMEB_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_TIME_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_SYSCALL_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_FILE_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_TIME_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_SYS_SOCKET_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_NETDB_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_FCNTL_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_STDARG_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_STDIO_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_ERRNO_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_WCHAR_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_ICONV_H */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_LIMITS_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_FTIME 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_GETADDRINFO 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_GETHOSTBYNAME_R 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_GETPID 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_GMTIME_R 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_HTONL 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_HTONS 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_LOCALTIME_R 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_LSTAT 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_FCNTL 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_LOCKF 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_FLOCK 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_NTOHL 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_NTOHS 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `shutdown' function. */
|
||||||
|
#define LOG4CPLUS_HAVE_SHUTDOWN 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_PIPE 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_PIPE2 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_POLL 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_POLL_H 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_STAT 1
|
||||||
|
|
||||||
|
/* Define if this is a single-threaded library. */
|
||||||
|
/* #undef LOG4CPLUS_SINGLE_THREADED */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* #undef LOG4CPLUS_USE_PTHREADS */
|
||||||
|
|
||||||
|
/* Define for compilers/standard libraries that support more than just the "C"
|
||||||
|
locale. */
|
||||||
|
/* #undef LOG4CPLUS_WORKING_LOCALE */
|
||||||
|
|
||||||
|
/* Define for C99 compilers/standard libraries that support more than just the
|
||||||
|
"C" locale. */
|
||||||
|
/* #undef LOG4CPLUS_WORKING_C_LOCALE */
|
||||||
|
|
||||||
|
/* Define to int if undefined. */
|
||||||
|
/* #undef socklen_t */
|
||||||
|
|
||||||
|
/* Defined for --enable-debugging builds. */
|
||||||
|
/* #undef LOG4CPLUS_DEBUGGING */
|
||||||
|
|
||||||
|
/* Defined if the compiler understands __declspec(dllexport) or
|
||||||
|
__attribute__((visibility("default"))) construct. */
|
||||||
|
#define LOG4CPLUS_DECLSPEC_EXPORT __attribute__ ((visibility("default")))
|
||||||
|
|
||||||
|
/* Defined if the compiler understands __declspec(dllimport) or
|
||||||
|
__attribute__((visibility("default"))) construct. */
|
||||||
|
#define LOG4CPLUS_DECLSPEC_IMPORT __attribute__ ((visibility("default")))
|
||||||
|
|
||||||
|
/* Defined if the compiler understands
|
||||||
|
__attribute__((visibility("hidden"))) construct. */
|
||||||
|
#define LOG4CPLUS_DECLSPEC_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_TLS_SUPPORT 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_THREAD_LOCAL_VAR thread_local
|
||||||
|
|
||||||
|
/* Defined if the host OS provides ENAMETOOLONG errno value. */
|
||||||
|
#define LOG4CPLUS_HAVE_ENAMETOOLONG 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define LOG4CPLUS_HAVE_VSNPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vsnwprintf' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_VSNWPRINTF */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_vsnwprintf' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* #undef LOG4CPLUS_HAVE__VSNPRINTF */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_VFPRINTF_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfwprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_VFWPRINTF_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vsprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_VSPRINTF_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vswprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_VSWPRINTF_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE__VSNPRINTF_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_vsnwprintf_s' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF_S */
|
||||||
|
|
||||||
|
/* Defined if the compiler supports __FUNCTION__ macro. */
|
||||||
|
#define LOG4CPLUS_HAVE_FUNCTION_MACRO 1
|
||||||
|
|
||||||
|
/* Defined if the compiler supports __PRETTY_FUNCTION__ macro. */
|
||||||
|
#define LOG4CPLUS_HAVE_PRETTY_FUNCTION_MACRO 1
|
||||||
|
|
||||||
|
/* Defined if the compiler supports __func__ symbol. */
|
||||||
|
#define LOG4CPLUS_HAVE_FUNC_SYMBOL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mbstowcs' function. */
|
||||||
|
#define LOG4CPLUS_HAVE_MBSTOWCS 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcstombs' function. */
|
||||||
|
#define LOG4CPLUS_HAVE_WCSTOMBS 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have Linux style syscall(SYS_gettid). */
|
||||||
|
#define LOG4CPLUS_HAVE_GETTID 1
|
||||||
|
|
||||||
|
/* Define when iconv() is available. */
|
||||||
|
/* #undef LOG4CPLUS_WITH_ICONV */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `iconv' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_ICONV */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `iconv_close' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_ICONV_CLOSE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `iconv_open' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_ICONV_OPEN */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `OutputDebugString' function. */
|
||||||
|
/* #undef LOG4CPLUS_HAVE_OUTPUTDEBUGSTRING */
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the `constructor' function attribute
|
||||||
|
with priority */
|
||||||
|
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR_PRIORITY 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the `constructor' function attribute */
|
||||||
|
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the `init_priority' variable attribute */
|
||||||
|
#define LOG4CPLUS_HAVE_VAR_ATTRIBUTE_INIT_PRIORITY 1
|
||||||
|
|
||||||
|
/* Defined to enable unit tests. */
|
||||||
|
/* #undef LOG4CPLUS_WITH_UNIT_TESTS */
|
||||||
|
|
||||||
|
#endif // LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||||
113
log4cplus/log4.h
113
log4cplus/log4.h
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <log4cplus/mdc.h> // ★新增:需要 MDCGuard
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -22,12 +24,9 @@
|
|||||||
|
|
||||||
#include "appender.h"
|
#include "appender.h"
|
||||||
|
|
||||||
#define LOGTYPE_COM 1
|
|
||||||
#define LOGTYPE_DATA 2
|
|
||||||
|
|
||||||
struct TypedLogger {
|
struct TypedLogger {
|
||||||
log4cplus::Logger logger;
|
log4cplus::Logger logger;
|
||||||
int logtype;
|
int code;
|
||||||
TypedLogger();
|
TypedLogger();
|
||||||
TypedLogger(const log4cplus::Logger& l, int t);
|
TypedLogger(const log4cplus::Logger& l, int t);
|
||||||
};
|
};
|
||||||
@@ -45,13 +44,14 @@ struct DebugSwitch {
|
|||||||
void set_level(int level);
|
void set_level(int level);
|
||||||
void enable_type(int type);
|
void enable_type(int type);
|
||||||
void disable_type(int type);
|
void disable_type(int type);
|
||||||
bool match(const std::string& logger_name, int level, int logtype);
|
bool match(const std::string& logger_name, int level, int code);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::map<std::string, TypedLogger> logger_map;
|
extern std::map<std::string, TypedLogger> logger_map;
|
||||||
extern DebugSwitch g_debug_switch;
|
extern DebugSwitch g_debug_switch;
|
||||||
|
|
||||||
extern void send_reply_to_kafka(const std::string& guid, const std::string& step, const std::string& result);
|
extern void send_reply_to_kafka(const std::string& guid, const std::string& step, const std::string& result);
|
||||||
|
extern void send_reply_to_kafka_recall(const std::string& guid, const std::string& step, const std::string& result,const std::string& lineIndex,const std::string& recallStartDate,const std::string& recallEndDate);
|
||||||
|
|
||||||
|
|
||||||
std::string get_front_type_from_subdir();
|
std::string get_front_type_from_subdir();
|
||||||
@@ -68,11 +68,14 @@ log4cplus::Logger init_logger(const std::string& full_name,
|
|||||||
const std::string& base_file,
|
const std::string& base_file,
|
||||||
log4cplus::SharedAppenderPtr fileAppender);
|
log4cplus::SharedAppenderPtr fileAppender);
|
||||||
|
|
||||||
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str);
|
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, int code);
|
||||||
|
|
||||||
|
|
||||||
void update_log_entries_countdown();
|
void update_log_entries_countdown();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////lnk20260306数据追踪
|
||||||
|
void process_trace_command(const std::string& id, int times);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void remove_loggers_by_terminal_id(const char* terminal_id_cstr);
|
void remove_loggers_by_terminal_id(const char* terminal_id_cstr);
|
||||||
@@ -86,21 +89,99 @@ void log_warn(const char* key, const char* msg);
|
|||||||
void log_error(const char* key, const char* msg);
|
void log_error(const char* key, const char* msg);
|
||||||
|
|
||||||
void send_reply_to_kafka_c(const char* guid, const char* step, const char* result);
|
void send_reply_to_kafka_c(const char* guid, const char* step, const char* result);
|
||||||
|
void send_reply_to_kafka_recall_c(const char* guid, const char* step, const char* result,const char* lineIndex,const char* recallStartDate,const char* recallEndDate);
|
||||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
|
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
|
||||||
|
|
||||||
//宏定义
|
// ====================== ★新增:线程局部变量透传 code ======================
|
||||||
#define DIY_LOG(LEVEL_FUNC, KEY, ...) \
|
// 说明:使用编译器的 TLS(__thread)保存当前日志的 code 值。
|
||||||
do { \
|
// 在每次打日志前写入,打完后恢复,Appender 读取该值写入 JSON。
|
||||||
char buf[256]; \
|
#if defined(__GNUC__)
|
||||||
format_log_msg(buf, sizeof(buf), __VA_ARGS__); \
|
#define LOG_TLS __thread
|
||||||
LEVEL_FUNC(KEY, buf); \
|
#else
|
||||||
|
// 若编译器不支持 __thread,可替换为 C++11 thread_local(但你的工程多为 C++98/C 混编,优先 __thread)
|
||||||
|
#define LOG_TLS __thread
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern LOG_TLS int g_log_code_tls; // 声明为 TLS 变量,定义见 log4.cpp
|
||||||
|
// ====================== ★新增结束 ======================
|
||||||
|
|
||||||
|
|
||||||
|
// ====================== 日志宏区域 ======================
|
||||||
|
|
||||||
|
#define DIY_LOG_CODE(LEVEL_FUNC, KEY, KEY_TYPE, CODE_INT, ...) \
|
||||||
|
do { \
|
||||||
|
int __old_code__ = g_log_code_tls; \
|
||||||
|
g_log_code_tls = (int)(CODE_INT); \
|
||||||
|
\
|
||||||
|
char __msg_buf__[512]; \
|
||||||
|
format_log_msg(__msg_buf__, sizeof(__msg_buf__), __VA_ARGS__); \
|
||||||
|
\
|
||||||
|
const char* __key_raw__ = (KEY); \
|
||||||
|
\
|
||||||
|
char __key_buf__[512]; \
|
||||||
|
switch ((int)(KEY_TYPE)) { \
|
||||||
|
case 0: \
|
||||||
|
snprintf(__key_buf__, sizeof(__key_buf__), "process"); \
|
||||||
|
break; \
|
||||||
|
case 1: \
|
||||||
|
snprintf(__key_buf__, sizeof(__key_buf__), \
|
||||||
|
"terminal.%s", __key_raw__); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
snprintf(__key_buf__, sizeof(__key_buf__), \
|
||||||
|
"monitor.%s", __key_raw__); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
snprintf(__key_buf__, sizeof(__key_buf__), "%s", \
|
||||||
|
__key_raw__); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
LEVEL_FUNC(__key_buf__, __msg_buf__); \
|
||||||
|
g_log_code_tls = __old_code__; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DIY_ERRORLOG(KEY, ...) DIY_LOG(log_error, KEY, __VA_ARGS__)
|
// ★修改:默认宏改为 code=0(兼容原有用法)
|
||||||
#define DIY_WARNLOG(KEY, ...) DIY_LOG(log_warn, KEY, __VA_ARGS__)
|
#define DIY_ERRORLOG(KEY, ...) DIY_LOG_CODE(log_error, KEY, 0, LOG_CODE_OTHER,__VA_ARGS__) // ★修改:默认 code=0
|
||||||
#define DIY_INFOLOG(KEY, ...) DIY_LOG(log_info, KEY, __VA_ARGS__)
|
#define DIY_WARNLOG(KEY, ...) DIY_LOG_CODE(log_warn, KEY, 0, LOG_CODE_OTHER,__VA_ARGS__) // ★修改:默认 code=0
|
||||||
#define DIY_DEBUGLOG(KEY, ...) DIY_LOG(log_debug, KEY, __VA_ARGS__)
|
#define DIY_INFOLOG(KEY, ...) DIY_LOG_CODE(log_info, KEY, 0, LOG_CODE_OTHER,__VA_ARGS__) // ★修改:默认 code=0
|
||||||
|
#define DIY_DEBUGLOG(KEY, ...) DIY_LOG_CODE(log_debug, KEY, 0, LOG_CODE_OTHER,__VA_ARGS__) // ★修改:默认 code=0
|
||||||
|
|
||||||
|
// ★新增:显式传入 code 的便捷宏
|
||||||
|
#define DIY_ERRORLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_error, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
|
||||||
|
#define DIY_WARNLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_warn, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
|
||||||
|
#define DIY_INFOLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_info, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
|
||||||
|
#define DIY_DEBUGLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_debug, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
|
||||||
|
|
||||||
|
|
||||||
|
// ====================== 日志宏区域 ======================
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum LogCode {
|
||||||
|
LOG_CODE_MENU_CONTROL = 94, /* 目录控制类型 */
|
||||||
|
LOG_CODE_FILE_CONTROL = 95, /* 文件控制类型 */
|
||||||
|
LOG_CODE_WIRETYPE = 96, /* 接线类型 */
|
||||||
|
LOG_CODE_CONFIG = 97, /* 配置相关 */
|
||||||
|
LOG_CODE_JSON = 98, /* JSON结构 */
|
||||||
|
LOG_CODE_OTHER = 99, /* 其他类型 */
|
||||||
|
LOG_CODE_LEDGER = 100, /* 台账类型 */
|
||||||
|
LOG_CODE_RPTINIT = 101, /* 报告初始化 */
|
||||||
|
LOG_CODE_ICD_AND_DOWNLOAD = 200, /* ICD 和文件下载类型 */
|
||||||
|
LOG_CODE_TRANSIENT = 300, /* 暂态发生 */
|
||||||
|
LOG_CODE_TRANSIENT_COMM = 301, /* 暂态接口 */
|
||||||
|
LOG_CODE_COMTRADE_FILE = 302, /* 录波文件(Comtrade) */
|
||||||
|
LOG_CODE_GGIO_LPHD = 304, /* GGIO事件 */
|
||||||
|
LOG_CODE_MQ = 400, /* MQ发送 */
|
||||||
|
LOG_CODE_RT_DATA = 401, /* 实时数据 */
|
||||||
|
LOG_CODE_LEDGER_UPDATE = 402, /* 台账更新 */
|
||||||
|
LOG_CODE_PROCESS_CONTROL = 403, /* 进程控制 */
|
||||||
|
LOG_CODE_RECALL = 404, /* 补招相关 */
|
||||||
|
LOG_CODE_LOG_REQUEST = 405, /* 日志请求 */
|
||||||
|
LOG_CODE_REPORT = 500, /* 报告处理 */
|
||||||
|
LOG_CODE_COMM = 600, /* 通讯状态 */
|
||||||
|
LOG_CODE_SPACE_ALARM = 700, /* 空间告警 */
|
||||||
|
LOG_CODE_DEVICE = 800 /* 设备告警 */
|
||||||
|
} LogCode;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,10 +45,10 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
extern char* OSS_ENDPOINT;
|
//extern char* OSS_ENDPOINT;
|
||||||
extern char* ACCESS_KEY_ID;
|
//extern char* ACCESS_KEY_ID;
|
||||||
extern char* ACCESS_KEY_SECRET;
|
//extern char* ACCESS_KEY_SECRET;
|
||||||
extern char* BUCKET_NAME;
|
//extern char* BUCKET_NAME;
|
||||||
|
|
||||||
extern char* POSTGRES_SCHEMA;
|
extern char* POSTGRES_SCHEMA;
|
||||||
extern char* POSTGRES_TABLEPREFIX;
|
extern char* POSTGRES_TABLEPREFIX;
|
||||||
@@ -105,16 +105,16 @@ void TestToken();
|
|||||||
void TestBodyPost();//WW 测试qt post
|
void TestBodyPost();//WW 测试qt post
|
||||||
void TestSMSPost();//WW 测试qt post
|
void TestSMSPost();//WW 测试qt post
|
||||||
void TestJson(char* szJson);
|
void TestJson(char* szJson);
|
||||||
void TestOSS();//WW 测试
|
//void TestOSS();//WW 测试
|
||||||
void PutOSS(char* File_Name, char* data); //zw修改 2023-9-7 上送oss文件
|
//void PutOSS(char* File_Name, char* data); //zw修改 2023-9-7 上送oss文件
|
||||||
void GetOSS(char* File_Name, char* savepath); //zw修改 2023-9-7 获取oss文件
|
//void GetOSS(char* File_Name, char* savepath); //zw修改 2023-9-7 获取oss文件
|
||||||
void DelOSS(char* File_Name);
|
//void DelOSS(char* File_Name);
|
||||||
void delete_object_new(char* File_Name);
|
void delete_object_new(char* File_Name);
|
||||||
void coutTest();//CZY 2023-09-11 test
|
void coutTest();//CZY 2023-09-11 test
|
||||||
void TestOBS();//WW 20230921 测试华为云服务器
|
//void TestOBS();//WW 20230921 测试华为云服务器
|
||||||
void OBSFile(char* localpath, char* cloudpath,const char* code);
|
//void OBSFile(char* localpath, char* cloudpath,const char* code);
|
||||||
void OBSFile_del(char* cloudpath, const char* code);
|
//void OBSFile_del(char* cloudpath, const char* code);
|
||||||
void DataHub_Send_Datahub(char* topic, char* data);//datahub通讯
|
//void DataHub_Send_Datahub(char* topic, char* data);//datahub通讯
|
||||||
void Nacos_GetParam(char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret);//nacos
|
void Nacos_GetParam(char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret);//nacos
|
||||||
void Nacos_GetParam_Ptr(const char* code, char** ptr);
|
void Nacos_GetParam_Ptr(const char* code, char** ptr);
|
||||||
void Read_Nacos_Param_Postgres(char** database_ip, char** database_port, char** postgres_database, char** postgres_username, char** postgres_password, char** postgres_schema, char** postgres_dnsname, char** postgres_tableprefix);
|
void Read_Nacos_Param_Postgres(char** database_ip, char** database_port, char** postgres_database, char** postgres_username, char** postgres_password, char** postgres_schema, char** postgres_dnsname, char** postgres_tableprefix);
|
||||||
@@ -152,6 +152,8 @@ int parse_model_cfg_web();
|
|||||||
void SOEFileWeb(char* localpath,char* cloudpath,char* wavepath);
|
void SOEFileWeb(char* localpath,char* cloudpath,char* wavepath);
|
||||||
const char* get_front_msg_from_subdir();
|
const char* get_front_msg_from_subdir();
|
||||||
|
|
||||||
|
char* find_mp_name_from_mp_id(const char* mp_id);
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -160,14 +162,33 @@ typedef struct {
|
|||||||
char WavePhasicB[64];
|
char WavePhasicB[64];
|
||||||
char WavePhasicC[64];
|
char WavePhasicC[64];
|
||||||
char UnitOfTimeUnit[64];
|
char UnitOfTimeUnit[64];
|
||||||
|
char TypeOfData[64];
|
||||||
char ValueOfTimeUnit[64];
|
char ValueOfTimeUnit[64];
|
||||||
char WaveTimeFlag[64];
|
char WaveTimeFlag[64];
|
||||||
|
char IEDControl[64];
|
||||||
char IEDname[64];
|
char IEDname[64];
|
||||||
char LDevicePrefix[64];
|
char LDevicePrefix[64];
|
||||||
} XmlConfigC;
|
} XmlConfigC;
|
||||||
|
|
||||||
bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg);
|
bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////文件控制请求参数
|
||||||
|
typedef struct file_dir_req_t
|
||||||
|
{
|
||||||
|
struct file_dir_req_t *next;
|
||||||
|
struct file_dir_req_t *prev;
|
||||||
|
|
||||||
|
char guid[128];
|
||||||
|
char frontid[128];
|
||||||
|
int processNo;
|
||||||
|
char devid[128];
|
||||||
|
int type;
|
||||||
|
char path[256];
|
||||||
|
char remote_path[256];
|
||||||
|
|
||||||
|
time_t create_time;
|
||||||
|
} file_dir_req_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ int main(int argc, const char **argv)
|
|||||||
//char buf[256];
|
//char buf[256];
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index);
|
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
//log_debug("process", buf);
|
//log_debug("process", buf);
|
||||||
DIY_WARNLOG("process","【WARN】前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_INFOLOG_CODE("process",0,LOG_CODE_OTHER,"【NORMAL】前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
#ifdef _OS_UNIX_
|
#ifdef _OS_UNIX_
|
||||||
#ifdef QT_NO_DEBUG
|
#ifdef QT_NO_DEBUG
|
||||||
@@ -268,7 +268,7 @@ int main(int argc, const char **argv)
|
|||||||
//char buf[256];
|
//char buf[256];
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
//log_error("process", buf);
|
//log_error("process", buf);
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_LEDGER,"【ERROR】前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ int main(int argc, const char **argv)
|
|||||||
//char buf[256];
|
//char buf[256];
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
//log_error("process", buf);
|
//log_error("process", buf);
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +324,7 @@ int main(int argc, const char **argv)
|
|||||||
//char buf[256];
|
//char buf[256];
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的业务线程死锁,退出进程");
|
//format_log_msg(buf,sizeof(buf),"前置的业务线程死锁,退出进程");
|
||||||
//log_error("process", buf);
|
//log_error("process", buf);
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 业务线程死锁,退出进程", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程 业务线程死锁,退出进程", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
apr_sleep(apr_time_from_sec(10));
|
apr_sleep(apr_time_from_sec(10));
|
||||||
exit(-1039);
|
exit(-1039);
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ extern apr_pool_t* g_cfg_pool;
|
|||||||
extern apr_pool_t* g_init_pool;
|
extern apr_pool_t* g_init_pool;
|
||||||
|
|
||||||
extern int g_DevFlag; //日志配置中读取的参数,暂无特定使用lnk20250121
|
extern int g_DevFlag; //日志配置中读取的参数,暂无特定使用lnk20250121
|
||||||
|
extern bool DEBUGOPEN;//调试开关,控制是否输出调试日志,默认关闭
|
||||||
extern int IED_COUNT;
|
extern int IED_COUNT;
|
||||||
|
extern int RECALL_ONLY_FLAG; //lnk20260309添加一个全局变量,标志是否只运行补招程序
|
||||||
|
|
||||||
//lnk20250115end
|
//lnk20250115end
|
||||||
|
|
||||||
@@ -150,13 +151,6 @@ void CloseIECReports(chnl_usr_t *chnl_usr)
|
|||||||
void closeChannel(chnl_usr_t *chnl_usr)
|
void closeChannel(chnl_usr_t *chnl_usr)
|
||||||
{
|
{
|
||||||
|
|
||||||
//终端日志的key,lnk20250526
|
|
||||||
char full_key_t_c[256]; // 分配足够空间
|
|
||||||
char full_key_t_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_t_c, sizeof(full_key_t_c), "terminal.%s.COM", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id);
|
|
||||||
snprintf(full_key_t_d, sizeof(full_key_t_d), "terminal.%s.DATA", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id);
|
|
||||||
//终端日志的key,lnk20250526
|
|
||||||
|
|
||||||
char comm_str[256];
|
char comm_str[256];
|
||||||
memset(comm_str,0,256);
|
memset(comm_str,0,256);
|
||||||
apr_snprintf(comm_str,sizeof(comm_str),"%16s:%d\t\tdisconnected !!!",chnl_usr->ip_str,chnl_usr->chnl->port);
|
apr_snprintf(comm_str,sizeof(comm_str),"%16s:%d\t\tdisconnected !!!",chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
@@ -184,7 +178,7 @@ void closeChannel(chnl_usr_t *chnl_usr)
|
|||||||
ret = mms_disconnectFromServer(chnl_usr->net_info,&chnl_usr->m_reqCtrl);
|
ret = mms_disconnectFromServer(chnl_usr->net_info,&chnl_usr->m_reqCtrl);
|
||||||
echo_warn("---------end disconnectFromServer!\n");
|
echo_warn("---------end disconnectFromServer!\n");
|
||||||
|
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】前置与终端%s - ip端口%s:%d 断开连接", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】前置与终端%s - ip端口%s:%d 断开连接", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
|
|
||||||
if (ret != SD_SUCCESS){
|
if (ret != SD_SUCCESS){
|
||||||
echo_warn("---------disconnectFromServer success!\n");
|
echo_warn("---------disconnectFromServer success!\n");
|
||||||
@@ -308,23 +302,33 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
{
|
{
|
||||||
LD_info = &(ied_usr->LD_info[cpuno]); //遍历监测点
|
LD_info = &(ied_usr->LD_info[cpuno]); //遍历监测点
|
||||||
|
|
||||||
if (LD_info->cpuno==0)
|
if (LD_info->cpuno==0){
|
||||||
|
// 仅在还没达到5次上限时打印
|
||||||
|
if (!LD_info->has_logged_regist) {
|
||||||
|
LD_info->registcount++;
|
||||||
|
|
||||||
|
if (LD_info->registcount <= 5) {
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【ERROR】监测点:%s - id:%s报告触发失败,监测点逻辑标识号为0,请检查装置对应的台账信息是否正确", LD_info->name,LD_info->mp_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 到5次就不再打印,并标记
|
||||||
|
if (LD_info->registcount > 5) {
|
||||||
|
LD_info->has_logged_regist = true;
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s监测点逻辑标识号错误日志已达本次记录上限,不再输出,请检查装置对应的台账信息是否正确",
|
||||||
|
LD_info->name, LD_info->mp_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(rpt_no=0 ; rpt_no<LD_info->rptcount; rpt_no++) { //遍历报告(映射文件中读取的报告控制)
|
for(rpt_no=0 ; rpt_no<LD_info->rptcount; rpt_no++) { //遍历报告(映射文件中读取的报告控制)
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", LD_info->mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", LD_info->mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
rptinfo = LD_info->rptinfo[rpt_no] ;
|
rptinfo = LD_info->rptinfo[rpt_no] ;
|
||||||
|
|
||||||
if (judge_rpt_next_should_do(rptinfo)==SHOULD_DO_NOTHING)//检查是否触发
|
if (judge_rpt_next_should_do(rptinfo)==SHOULD_DO_NOTHING)//检查是否触发
|
||||||
{
|
{
|
||||||
//DIY_DEBUGLOG(full_key_m_c,"【DEBUG】监测点:%s - id:%s不注册报告", LD_info->name,LD_info->mp_id);
|
//DIY_DEBUGLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【DEBUG】监测点:%s - id:%s不注册报告", LD_info->name,LD_info->mp_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +344,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
printf("start mms_register_iec_rpt................................\n");
|
printf("start mms_register_iec_rpt................................\n");
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s开始注册报告,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】监测点:%s - id:%s开始注册报告,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
|
|
||||||
if ( strstr(rptinfo->rptID,"LLN0$BR$brcbFlickerData") )
|
if ( strstr(rptinfo->rptID,"LLN0$BR$brcbFlickerData") )
|
||||||
rptinfo->IntgPd = 600; //10分钟
|
rptinfo->IntgPd = 600; //10分钟
|
||||||
@@ -363,7 +367,22 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
chnl_usr->chnl_id, rptinfo->IntgPd,rptinfo->TrgOpt );
|
chnl_usr->chnl_id, rptinfo->IntgPd,rptinfo->TrgOpt );
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s注册报告失败,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
// 仅在还没达到5次上限时打印
|
||||||
|
if (!LD_info->has_logged_regist) {
|
||||||
|
LD_info->registcount++;
|
||||||
|
|
||||||
|
if (LD_info->registcount <= 5) {
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT, "【WARN】监测点:%s - id:%s注册报告失败,报告名:%s",
|
||||||
|
LD_info->name, LD_info->mp_id, rpt_inst_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 到5次就不再打印,并标记
|
||||||
|
if (LD_info->registcount > 5) {
|
||||||
|
LD_info->has_logged_regist = true;
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注册报告失败日志已达本次注册上限,不再输出,请检查装置icd和映射文件是否匹配或者装置存在过多连接",
|
||||||
|
LD_info->name, LD_info->mp_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -381,7 +400,9 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
rptinfo->IntgPd,rptinfo->TrgOpt,rptinfo->OptFlds[0],rptinfo->OptFlds[1] );
|
rptinfo->IntgPd,rptinfo->TrgOpt,rptinfo->OptFlds[0],rptinfo->OptFlds[1] );
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s注册报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
LD_info->has_logged_regist = FALSE;
|
||||||
|
LD_info->registcount = 0;
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注册报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
|
|
||||||
// add here to GI not the same time
|
// add here to GI not the same time
|
||||||
GIoffset = 0.5 * g_pt61850app->giTime;
|
GIoffset = 0.5 * g_pt61850app->giTime;
|
||||||
@@ -389,7 +410,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
}
|
}
|
||||||
printf("end mms_register_iec_rpt................................\n");
|
printf("end mms_register_iec_rpt................................\n");
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s注册报告结束,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】监测点:%s - id:%s注册报告结束,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { //rpt_registered ==TRUE
|
else { //rpt_registered ==TRUE
|
||||||
@@ -398,7 +419,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
printf("start mms_unregister_iec_rpt................................\n");
|
printf("start mms_unregister_iec_rpt................................\n");
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s开始注销报告,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】监测点:%s - id:%s开始注销报告,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
|
|
||||||
ret = mms_unregister_iec_rpt (chnl_usr->net_info, &g_rpt_typeids,
|
ret = mms_unregister_iec_rpt (chnl_usr->net_info, &g_rpt_typeids,
|
||||||
LD_info->LD_name,rpt_inst_name,g_pt61850app->mmsOpTimeout);
|
LD_info->LD_name,rpt_inst_name,g_pt61850app->mmsOpTimeout);
|
||||||
@@ -409,7 +430,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
APR_EGENERAL, LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl_id);
|
APR_EGENERAL, LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl_id);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s注销报告失败,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注销报告失败,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -418,11 +439,11 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr)
|
|||||||
LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl->port,chnl_usr->chnl_id );
|
LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl->port,chnl_usr->chnl_id );
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s注销报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】监测点:%s - id:%s注销报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
}
|
}
|
||||||
printf("end mms_unregister_iec_rpt................................\n");
|
printf("end mms_unregister_iec_rpt................................\n");
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s注销报告结束,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】监测点:%s - id:%s注销报告结束,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -448,6 +469,15 @@ void ChannelCheckWaveFiles(chnl_usr_t *chnl_usr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lnk20250821时间转换:秒转本地时间
|
||||||
|
static void sec_to_timestr(long long sec, char *out, size_t out_sz)
|
||||||
|
{
|
||||||
|
time_t t = (time_t)sec;
|
||||||
|
struct tm tmv;
|
||||||
|
localtime_r(&t, &tmv); // 本地时间
|
||||||
|
strftime(out, out_sz, "%Y-%m-%d %H:%M:%S", &tmv);
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
||||||
{
|
{
|
||||||
ST_RET ret;
|
ST_RET ret;
|
||||||
@@ -466,18 +496,30 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
|||||||
for(cpuno=0 ; cpuno<ied->cpucount; cpuno++) {
|
for(cpuno=0 ; cpuno<ied->cpucount; cpuno++) {
|
||||||
LD_info = &(ied_usr->LD_info[cpuno]);
|
LD_info = &(ied_usr->LD_info[cpuno]);
|
||||||
|
|
||||||
if (LD_info->logcount<=0)
|
//日志控制块缺失
|
||||||
|
if (LD_info->logcount<=0){
|
||||||
|
// 仅在还没达到5次上限时打印
|
||||||
|
if (!LD_info->has_logged_regist) {
|
||||||
|
LD_info->registcount++;
|
||||||
|
|
||||||
|
if (LD_info->registcount <= 5) {
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【ERROR】监测点:%s - id:%s补招数据失败,监测点缺少日志控制块,请检查装置对应的装置类型是否有配对的icd模型", LD_info->name,LD_info->mp_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 到5次就不再打印,并标记
|
||||||
|
if (LD_info->registcount > 5) {
|
||||||
|
LD_info->has_logged_regist = true;
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s缺少日志控制块日志已达本次记录上限,不再输出,请检查装置对应的装置类型是否有配对的icd模型",
|
||||||
|
LD_info->name, LD_info->mp_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
loginfo = LD_info->loginfo[0] ;
|
loginfo = LD_info->loginfo[0] ;
|
||||||
|
|
||||||
apr_sleep(apr_time_from_sec(1) / 10);
|
apr_sleep(apr_time_from_sec(1) / 10);
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", LD_info->mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", LD_info->mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
Check_Recall_Config(LD_info->mp_id);//尝试获取xml结构
|
Check_Recall_Config(LD_info->mp_id);//尝试获取xml结构
|
||||||
|
|
||||||
@@ -498,28 +540,41 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
|||||||
|
|
||||||
if(strcmp(cfg1.ValueOfTimeUnit, "utc") == 0){//装置时间是utc还是北京
|
if(strcmp(cfg1.ValueOfTimeUnit, "utc") == 0){//装置时间是utc还是北京
|
||||||
utc_or_beijing = 28800;//秒
|
utc_or_beijing = 28800;//秒
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为utc时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为utc时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
utc_or_beijing = 0;
|
utc_or_beijing = 0;
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
//记录本次补招的时间范围
|
||||||
|
long long min_start_sec = LLONG_MAX;
|
||||||
|
long long max_end_sec = 0;
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
for (i = 0; i < LD_info->autorecallcount; i++) {
|
for (i = 0; i < LD_info->autorecallcount; i++) {
|
||||||
|
|
||||||
|
// ===== [新增] 累计全局最小/最大区间(直接用原始 start/end)=====
|
||||||
|
if (LD_info->autorecall[i]->start < min_start_sec) {
|
||||||
|
min_start_sec = LD_info->autorecall[i]->start;
|
||||||
|
}
|
||||||
|
if (LD_info->autorecall[i]->end > max_end_sec) {
|
||||||
|
max_end_sec = LD_info->autorecall[i]->end;
|
||||||
|
}
|
||||||
|
// ===== [新增结束] =====
|
||||||
|
|
||||||
LD_info->autorecallflag = 1;//正在补招
|
LD_info->autorecallflag = 1;//正在补招
|
||||||
|
|
||||||
//当前不区分稳态和暂态lnk20241030,如果做区分修改:Check_Recall_Config从xml文件获取数据后,赋值给了LD_info
|
//当前不区分稳态和暂态lnk20241030,如果做区分修改:Check_Recall_Config从xml文件获取数据后,赋值给了LD_info
|
||||||
loginfo->need_steady = LD_info->autorecall[i]->need_steady; loginfo->need_voltage = LD_info->autorecall[i]->need_voltage;
|
loginfo->need_steady = LD_info->autorecall[i]->need_steady; loginfo->need_voltage = LD_info->autorecall[i]->need_voltage;
|
||||||
|
|
||||||
loginfo->start_time = apr_time_from_sec(LD_info->autorecall[i]->start - 5);//保证时间开头
|
loginfo->start_time = apr_time_from_sec(LD_info->autorecall[i]->start - 5);//保证时间开头
|
||||||
loginfo->end_time = apr_time_from_sec(LD_info->autorecall[i]->end - 5);//不保证时间结尾,可以+5保证时间结尾
|
loginfo->end_time = apr_time_from_sec(LD_info->autorecall[i]->end - 5);//不保证时间结尾
|
||||||
|
|
||||||
/////////////////////////////////////////////////////根据配置文件控制下发补招时间为北京时间还是utc时间,上送的数据61850库会转换成北京时间?
|
/////////////////////////////////////////////////////根据配置文件控制下发补招时间为北京时间还是utc时间,上送的数据61850库会转换成北京时间?
|
||||||
loginfo->start_time = loginfo->start_time - utc_or_beijing;//下发utc时间需要减去8小时-秒
|
loginfo->start_time = loginfo->start_time - utc_or_beijing * APR_USEC_PER_SEC;//下发utc时间需要减去8小时-秒
|
||||||
loginfo->end_time = loginfo->end_time - utc_or_beijing;
|
loginfo->end_time = loginfo->end_time - utc_or_beijing * APR_USEC_PER_SEC;
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (loginfo->need_steady == 0 && loginfo->need_voltage == 0)
|
if (loginfo->need_steady == 0 && loginfo->need_voltage == 0)
|
||||||
@@ -533,7 +588,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
|||||||
LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id);
|
LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
//DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s开始补招数据", LD_info->name,LD_info->mp_id);
|
//DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据", LD_info->name,LD_info->mp_id);
|
||||||
|
|
||||||
ret = mms_jread(loginfo, chnl_usr->net_info, loginfo->LD_info->LD_name, loginfo->logName,
|
ret = mms_jread(loginfo, chnl_usr->net_info, loginfo->LD_info->LD_name, loginfo->logName,
|
||||||
loginfo->start_time, loginfo->end_time, g_pt61850app->mmsOpTimeout, chnl_usr->ip_str);
|
loginfo->start_time, loginfo->end_time, g_pt61850app->mmsOpTimeout, chnl_usr->ip_str);
|
||||||
@@ -542,7 +597,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
|||||||
LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id);
|
LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_ERRORLOG(full_key_m_c,"【ERROR】监测点:%s - id:%s补招数据失败 - 失败时间点:%lld 至 %lld", LD_info->name,LD_info->mp_id,loginfo->start_time,loginfo->end_time);
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【ERROR】监测点:%s - id:%s补招数据失败 - 失败时间点:%lld 至 %lld", LD_info->name,LD_info->mp_id,loginfo->start_time,loginfo->end_time);
|
||||||
|
|
||||||
failed_count++;
|
failed_count++;
|
||||||
}
|
}
|
||||||
@@ -565,7 +620,37 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
|
|||||||
//不管是否成功,这个补招文件必须删除,可能出现一直失败,循环读取文件和循环补招导致程序崩溃202050724lnk
|
//不管是否成功,这个补招文件必须删除,可能出现一直失败,循环读取文件和循环补招导致程序崩溃202050724lnk
|
||||||
//if (failed_count==0) {//成功
|
//if (failed_count==0) {//成功
|
||||||
Delete_recall_Xml(LD_info->mp_id);
|
Delete_recall_Xml(LD_info->mp_id);
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s结束补招数据", LD_info->name,LD_info->mp_id);
|
|
||||||
|
// ===== [新增] 组装上送的补招开始/结束时间字符串(本地时区,直接“秒转字符串”)=====
|
||||||
|
char recallStartDate[32] = {0};
|
||||||
|
char recallEndDate[32] = {0};
|
||||||
|
|
||||||
|
if (min_start_sec == LLONG_MAX) {
|
||||||
|
// 理论上不会进来:有 autorecallcount != 0。兜底写成当前时间
|
||||||
|
time_t nowt = time(NULL);
|
||||||
|
sec_to_timestr((long long)nowt, recallStartDate, sizeof(recallStartDate));
|
||||||
|
sec_to_timestr((long long)nowt, recallEndDate, sizeof(recallEndDate));
|
||||||
|
} else {
|
||||||
|
sec_to_timestr(min_start_sec, recallStartDate, sizeof(recallStartDate));
|
||||||
|
sec_to_timestr(max_end_sec, recallEndDate, sizeof(recallEndDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
//拼接result
|
||||||
|
const char *ld_name_safe = (LD_info->name && LD_info->name[0])
|
||||||
|
? LD_info->name : "-";
|
||||||
|
|
||||||
|
char result_buf[256];
|
||||||
|
snprintf(result_buf, sizeof(result_buf),
|
||||||
|
"监测点:%s 补招时间最小值和最大值:%s ~ %s 本次补招执行结束",
|
||||||
|
ld_name_safe, recallStartDate, recallEndDate);
|
||||||
|
|
||||||
|
// guid 固定 "12345",step 固定 "2"
|
||||||
|
//send_reply_to_kafka_c("12345", "2", result_buf);
|
||||||
|
send_reply_to_kafka_recall_c("12345", "2", result_buf,LD_info->mp_id,recallStartDate,recallEndDate);
|
||||||
|
|
||||||
|
// ===== [新增结束] =====
|
||||||
|
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s结束补招数据", LD_info->name,LD_info->mp_id);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,7 +781,7 @@ void process_3s_config(trigger_3s_xml_t *trigger_3s_xml)
|
|||||||
create_3s_xml(trigger_3s_xml); //写入文件的work块
|
create_3s_xml(trigger_3s_xml); //写入文件的work块
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_process_recall_config(recall_xml_t* recall_xml)
|
/*void del_process_recall_config(recall_xml_t* recall_xml)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
recall_t *recall;
|
recall_t *recall;
|
||||||
@@ -733,7 +818,7 @@ void del_process_recall_config(recall_xml_t* recall_xml)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void check_3s_config()
|
void check_3s_config()
|
||||||
{
|
{
|
||||||
@@ -1013,9 +1098,9 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
|
|||||||
//关闭这个终端的所有连接//////////////////////////////////////////////////////////////////////
|
//关闭这个终端的所有连接//////////////////////////////////////////////////////////////////////
|
||||||
for(chnl_no=0 ; chnl_no<ied->chncount; chnl_no++) {
|
for(chnl_no=0 ; chnl_no<ied->chncount; chnl_no++) {
|
||||||
chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;
|
chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;
|
||||||
if (chnl_usr->m_state!=CHANNEL_CONNECTED){//跳过未连接的通道
|
/*if (chnl_usr->m_state!=CHANNEL_CONNECTED){//跳过未连接的通道
|
||||||
continue;
|
continue;
|
||||||
}
|
}*///20260416任何状态都关闭连接
|
||||||
closeChannel(chnl_usr);//关闭更新台账后,任务会自动连接
|
closeChannel(chnl_usr);//关闭更新台账后,任务会自动连接
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1126,9 +1211,9 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
|
|||||||
//关闭这个终端的所有连接//////////////////////////////////////////////////////////////////////
|
//关闭这个终端的所有连接//////////////////////////////////////////////////////////////////////
|
||||||
for(chnl_no=0 ; chnl_no<ied->chncount; chnl_no++) {
|
for(chnl_no=0 ; chnl_no<ied->chncount; chnl_no++) {
|
||||||
chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;
|
chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;
|
||||||
if (chnl_usr->m_state!=CHANNEL_CONNECTED){ //跳过没连接的通道,一般一个终端只有一个
|
/*if (chnl_usr->m_state!=CHANNEL_CONNECTED){ //跳过没连接的通道,一般一个终端只有一个
|
||||||
continue;
|
continue;
|
||||||
}
|
}*///20260416任何状态都关闭连接
|
||||||
closeChannel(chnl_usr);//关闭更新台账后,如果是删除则不会再连接,关闭连接时这个ied的报告会被清除,报告控制会被注销
|
closeChannel(chnl_usr);//关闭更新台账后,如果是删除则不会再连接,关闭连接时这个ied的报告会被清除,报告控制会被注销
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1223,6 +1308,7 @@ void print_monitor(const monitor* mon) {
|
|||||||
printf("Terminal Connect: %s\n", is_empty(mon->terminal_connect) ? "N/A" : mon->terminal_connect);
|
printf("Terminal Connect: %s\n", is_empty(mon->terminal_connect) ? "N/A" : mon->terminal_connect);
|
||||||
printf("Timestamp: %s\n", is_empty(mon->timestamp) ? "N/A" : mon->timestamp);
|
printf("Timestamp: %s\n", is_empty(mon->timestamp) ? "N/A" : mon->timestamp);
|
||||||
printf("Status: %s\n", is_empty(mon->status) ? "N/A" : mon->status);
|
printf("Status: %s\n", is_empty(mon->status) ? "N/A" : mon->status);
|
||||||
|
printf("Log Level: %d\n", mon->log_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印 terminal 结构体信息
|
// 打印 terminal 结构体信息
|
||||||
@@ -1241,6 +1327,7 @@ void print_terminal(const terminal* tmnl) {
|
|||||||
printf("Address: %s\n", is_empty(tmnl->addr_str) ? "N/A" : tmnl->addr_str);
|
printf("Address: %s\n", is_empty(tmnl->addr_str) ? "N/A" : tmnl->addr_str);
|
||||||
printf("Port: %s\n", is_empty(tmnl->port) ? "N/A" : tmnl->port);
|
printf("Port: %s\n", is_empty(tmnl->port) ? "N/A" : tmnl->port);
|
||||||
printf("Timestamp: %s\n", is_empty(tmnl->timestamp) ? "N/A" : tmnl->timestamp);
|
printf("Timestamp: %s\n", is_empty(tmnl->timestamp) ? "N/A" : tmnl->timestamp);
|
||||||
|
printf("Log Level: %d\n", tmnl->log_level);
|
||||||
|
|
||||||
// 打印监测点信息,如果监测点字段为空,则打印 N/A
|
// 打印监测点信息,如果监测点字段为空,则打印 N/A
|
||||||
int i;
|
int i;
|
||||||
@@ -1311,11 +1398,14 @@ void check_ledger_update()//lnk20250113
|
|||||||
//调试用
|
//调试用
|
||||||
print_trigger_update_xml(trigger_ledger_update_xml);
|
print_trigger_update_xml(trigger_ledger_update_xml);
|
||||||
|
|
||||||
//处理台账更新加台账锁lnk20250114
|
//处理台账更新添加控制标志
|
||||||
//pthread_mutex_lock(&mtx); printf("ledgerupdate hold lock !!!!!!!!!!!");
|
if (RECALL_ONLY_FLAG != 1 || (g_node_id != STAT_DATA_BASE_NODE_ID)) {
|
||||||
process_ledger_update(trigger_ledger_update_xml); //台账更新
|
process_ledger_update(trigger_ledger_update_xml); //台账更新
|
||||||
//pthread_mutex_unlock(&mtx); printf("ledgerupdate free lock !!!!!!!!!!!");
|
}
|
||||||
|
else{
|
||||||
|
printf("only process recall config, skip ledger update\n");
|
||||||
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_SPACE_ALARM,"【WARN】当前配置为仅日志模式,统计数据进程跳过台账更新");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用完后释放动态分配的内存
|
// 使用完后释放动态分配的内存
|
||||||
@@ -1370,13 +1460,13 @@ void check_disk_quota()
|
|||||||
//printf("Current user disk free size: %dMB ,total size: %dMB \n",freeSizeMB,totalSizeMB);
|
//printf("Current user disk free size: %dMB ,total size: %dMB \n",freeSizeMB,totalSizeMB);
|
||||||
if (freeSizeMB<g_min_free_size){
|
if (freeSizeMB<g_min_free_size){
|
||||||
echo_warn2("Current user disk free size: %dMB < %dMB, please check!\n",freeSizeMB,g_min_free_size);
|
echo_warn2("Current user disk free size: %dMB < %dMB, please check!\n",freeSizeMB,g_min_free_size);
|
||||||
DIY_WARNLOG("process","【WARN】前置磁盘检测: 当前磁盘的可用空间为%dMB,小于最小可用空间%dMB,请检查磁盘",freeSizeMB,g_min_free_size);
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_SPACE_ALARM,"【WARN】前置磁盘检测: 当前磁盘的可用空间为%dMB,小于最小可用空间%dMB,请检查磁盘",freeSizeMB,g_min_free_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((freeSizeMB/(totalSizeMB/100+1) )<10){
|
if ((freeSizeMB/(totalSizeMB/100+1) )<10){
|
||||||
echo_warn2("Current user disk free size percent < 10%%, free size: %dMB ,total size: %dMB ,please check!\n",
|
echo_warn2("Current user disk free size percent < 10%%, free size: %dMB ,total size: %dMB ,please check!\n",
|
||||||
freeSizeMB,totalSizeMB);
|
freeSizeMB,totalSizeMB);
|
||||||
DIY_WARNLOG("process","【WARN】前置磁盘检测: 当前磁盘的可用空间的百分比小于10%%,可用空间为%dMB,总空间为%dMB,请检查磁盘",freeSizeMB,totalSizeMB);
|
DIY_WARNLOG_CODE("process",0,LOG_CODE_SPACE_ALARM,"【WARN】前置磁盘检测: 当前磁盘的可用空间的百分比小于10%%,可用空间为%dMB,总空间为%dMB,请检查磁盘",freeSizeMB,totalSizeMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1402,9 +1492,14 @@ void Check_Recall_Config(char *id) //检查补招配置文件Recall.xml
|
|||||||
if (g_node_id == HIS_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID || g_node_id == RECALL_HIS_DATA_BASE_NODE_ID || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) {
|
if (g_node_id == HIS_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID || g_node_id == RECALL_HIS_DATA_BASE_NODE_ID || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) {
|
||||||
|
|
||||||
recall_xml_t recall_xml;
|
recall_xml_t recall_xml;
|
||||||
memset((char*)&recall_xml, 0, sizeof(recall_xml_t));
|
//memset((char*)&recall_xml, 0, sizeof(recall_xml_t));
|
||||||
|
|
||||||
|
recall_xml_init(&recall_xml);
|
||||||
|
|
||||||
parse_recall_xml(&recall_xml,id); //解析补招文件,目录下所有属于这个监测点的文件都读取
|
parse_recall_xml(&recall_xml,id); //解析补招文件,目录下所有属于这个监测点的文件都读取
|
||||||
process_recall_config(&recall_xml); //解析的补招数据赋值到全局变量
|
process_recall_config(&recall_xml); //解析的补招数据赋值到全局变量
|
||||||
|
|
||||||
|
recall_xml_free(&recall_xml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1435,6 +1530,11 @@ void CheckAllConnectedChannel()
|
|||||||
|
|
||||||
if(chnl_usr->m_state == CHANNEL_CONNECTED)
|
if(chnl_usr->m_state == CHANNEL_CONNECTED)
|
||||||
{
|
{
|
||||||
|
if(g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {
|
||||||
|
InitLedrsOperTypeForChannel(chnl_usr);//写特殊控制的初始化
|
||||||
|
if(DEBUGOPEN)printf("[FILEDIR] enter HandleFileDirReqForChannel");
|
||||||
|
HandleFileDirReqForChannel(chnl_usr);//文件目录请求
|
||||||
|
}
|
||||||
|
|
||||||
ChannelCheckIECReports(chnl_usr);//报告
|
ChannelCheckIECReports(chnl_usr);//报告
|
||||||
if ( (g_node_id == SOE_COMTRADE_BASE_NODE_ID) || (g_node_id == HIS_DATA_BASE_NODE_ID) || (g_node_id == NEW_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID))
|
if ( (g_node_id == SOE_COMTRADE_BASE_NODE_ID) || (g_node_id == HIS_DATA_BASE_NODE_ID) || (g_node_id == NEW_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID))
|
||||||
@@ -1490,13 +1590,6 @@ void CheckNextNotConnectedChannel()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//终端日志的key,lnk20250526
|
|
||||||
char full_key_t_c[256]; // 分配足够空间
|
|
||||||
char full_key_t_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_t_c, sizeof(full_key_t_c), "terminal.%s.COM", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id);
|
|
||||||
snprintf(full_key_t_d, sizeof(full_key_t_d), "terminal.%s.DATA", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id);
|
|
||||||
//终端日志的key,lnk20250526
|
|
||||||
|
|
||||||
//10-11-01 22:03 beijing
|
//10-11-01 22:03 beijing
|
||||||
if( ( (chnl_total_no+1)==g_pt61850app->chnl_counts) || (g_onlyIP[0]!=0) ){
|
if( ( (chnl_total_no+1)==g_pt61850app->chnl_counts) || (g_onlyIP[0]!=0) ){
|
||||||
if(g_pt61850app->initNum<255)
|
if(g_pt61850app->initNum<255)
|
||||||
@@ -1522,7 +1615,7 @@ void CheckNextNotConnectedChannel()
|
|||||||
//mq日志
|
//mq日志
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = true;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = true;
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = false;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = false;
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d连接成功", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d连接成功", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
|
|
||||||
mvl_free_req_ctrl(chnl_usr->m_reqCtrl);
|
mvl_free_req_ctrl(chnl_usr->m_reqCtrl);
|
||||||
chnl_usr->m_reqCtrl = NULL;
|
chnl_usr->m_reqCtrl = NULL;
|
||||||
@@ -1569,18 +1662,26 @@ void CheckNextNotConnectedChannel()
|
|||||||
if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){
|
if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false;
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip/端口:%s:%d,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,secsSince);
|
||||||
}
|
}
|
||||||
else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){
|
else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip/端口:%s:%d,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,secsSince);
|
||||||
}
|
}
|
||||||
|
|
||||||
mvl_free_req_ctrl(chnl_usr->m_reqCtrl);
|
mvl_free_req_ctrl(chnl_usr->m_reqCtrl);
|
||||||
chnl_usr->m_reqCtrl = NULL;
|
chnl_usr->m_reqCtrl = NULL;
|
||||||
chnl_usr->net_info->rem_vmd = NULL;
|
chnl_usr->net_info->rem_vmd = NULL;
|
||||||
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
||||||
chnl_usr->m_ClosedMsTime = sGetMsTime();
|
chnl_usr->m_ClosedMsTime = sGetMsTime();
|
||||||
|
|
||||||
|
//断联成功
|
||||||
|
|
||||||
|
apr_time_t t_now = apr_time_now();
|
||||||
|
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
||||||
|
//更新状态
|
||||||
|
chnl_usr->chnl->ied->status = STATUS_OVERTIME;
|
||||||
|
chnl_usr->chnl->status = STATUS_OVERTIME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1596,11 +1697,11 @@ void CheckNextNotConnectedChannel()
|
|||||||
if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){
|
if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false;
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
}
|
}
|
||||||
else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){
|
else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){
|
||||||
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true;
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1615,6 +1716,14 @@ void CheckNextNotConnectedChannel()
|
|||||||
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
||||||
chnl_usr->m_ClosedMsTime = sGetMsTime();
|
chnl_usr->m_ClosedMsTime = sGetMsTime();
|
||||||
|
|
||||||
|
//断联
|
||||||
|
|
||||||
|
apr_time_t t_now = apr_time_now();
|
||||||
|
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
||||||
|
//更新状态
|
||||||
|
chnl_usr->chnl->ied->status = STATUS_OVERTIME;
|
||||||
|
chnl_usr->chnl->status = STATUS_OVERTIME;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1632,7 +1741,7 @@ void CheckNextNotConnectedChannel()
|
|||||||
if (chnl_usr->chnl->ied->cpucount != NULL && chnl_usr->chnl->ied->cpucount > 0 && ied_usr->dev_flag == ENABLE) {//2023-09-26 czy 如果line count<0 不需要连接//lnk20250121如果终端无效则不连接
|
if (chnl_usr->chnl->ied->cpucount != NULL && chnl_usr->chnl->ied->cpucount > 0 && ied_usr->dev_flag == ENABLE) {//2023-09-26 czy 如果line count<0 不需要连接//lnk20250121如果终端无效则不连接
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
//DIY_WARNLOG(full_key_t_c,"【WARN】重新连接终端%s - ip端口:%s:%d", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
//DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】重新连接终端%s - ip端口:%s:%d", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
|
|
||||||
ret = mms_connectToServer(ied_usr->dev_key, ied_usr->dev_series, serverARName, &(chnl_usr->net_info), &(chnl_usr->m_reqCtrl));
|
ret = mms_connectToServer(ied_usr->dev_key, ied_usr->dev_series, serverARName, &(chnl_usr->net_info), &(chnl_usr->m_reqCtrl));
|
||||||
|
|
||||||
@@ -1644,7 +1753,7 @@ void CheckNextNotConnectedChannel()
|
|||||||
chnl_usr->m_StartConnectingTime = sGetMsTime();
|
chnl_usr->m_StartConnectingTime = sGetMsTime();
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
//DIY_WARNLOG(full_key_t_c,"【WARN】正在重新连接终端%s - ip端口:%s:%d - 识别码/秘钥:%s/%s", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key);
|
//DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】正在重新连接终端%s - ip端口:%s:%d - 识别码/秘钥:%s/%s", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1656,7 +1765,7 @@ void CheckNextNotConnectedChannel()
|
|||||||
echo_warn3("FAILED: mms_connectToServer IP %s:%d ,NetInfo= %x \n", chnl_usr->ip_str, chnl_usr->chnl->port, chnl_usr->net_info);
|
echo_warn3("FAILED: mms_connectToServer IP %s:%d ,NetInfo= %x \n", chnl_usr->ip_str, chnl_usr->chnl->port, chnl_usr->net_info);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
//DIY_WARNLOG(full_key_t_c,"【WARN】重新连接终端%s - ip端口:%s:%d 失败!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
//DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】重新连接终端%s - ip端口:%s:%d 失败!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1682,9 +1791,12 @@ void CheckNextNotConnectedChannel()
|
|||||||
ied_usr_t* ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext;
|
ied_usr_t* ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext;
|
||||||
apr_time_t t_now = apr_time_now();
|
apr_time_t t_now = apr_time_now();
|
||||||
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
||||||
|
//更新状态
|
||||||
|
chnl_usr->chnl->ied->status = STATUS_BREAKOFF;
|
||||||
|
chnl_usr->chnl->status = STATUS_BREAKOFF;
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d 断连完成,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d 断连完成,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1709,9 +1821,12 @@ void CheckNextNotConnectedChannel()
|
|||||||
ied_usr_t* ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext;
|
ied_usr_t* ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext;
|
||||||
apr_time_t t_now = apr_time_now();
|
apr_time_t t_now = apr_time_now();
|
||||||
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0);
|
||||||
|
//更新状态
|
||||||
|
chnl_usr->chnl->ied->status = STATUS_BREAKOFF;
|
||||||
|
chnl_usr->chnl->status = STATUS_BREAKOFF;
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d 断连未完成,但是已经超时180秒,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
DIY_WARNLOG_CODE(((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,1,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d 断连未完成,但是已经超时180秒,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1826,6 +1941,29 @@ apr_status_t prepare_call_cn_wavelist(LD_info_t *LD_info, int FltNum)
|
|||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//判断暂态记录非空,lnk20250818
|
||||||
|
int ld_has_qvvr_nonempty(const LD_info_t* info)
|
||||||
|
{
|
||||||
|
if (!info) return 0;
|
||||||
|
|
||||||
|
/* 规则1:索引计数 > 0 直接认为非空 */
|
||||||
|
if (info->qvvr_idx > 0) return 1;
|
||||||
|
|
||||||
|
/* 规则2:扫描数组,任意一项出现被使用/有时间/有名称/有数值 即认为非空 */
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < QVVR_NUM; ++i) {
|
||||||
|
const QVVR_t* it = &info->qvvr[i];
|
||||||
|
|
||||||
|
if (it->used_status != 0 && it->QVVR_time != 0 && it->QVVR_PerTime != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 都没有则为空 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
||||||
{
|
{
|
||||||
int ret ;
|
int ret ;
|
||||||
@@ -1840,13 +1978,6 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
||||||
int have_new_files = FALSE;
|
int have_new_files = FALSE;
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", LD_info->mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", LD_info->mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
for (i=0;i<256;i++) {
|
for (i=0;i<256;i++) {
|
||||||
if (LD_info->FltNum[i]<=0)
|
if (LD_info->FltNum[i]<=0)
|
||||||
continue;
|
continue;
|
||||||
@@ -1858,7 +1989,7 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
printf(">>>>>>>> IED [%d]: %s is calling cn wavefile, !!!!!!!! file_match_str=%s \n",ied->id,ied->name,file_match_str);
|
printf(">>>>>>>> IED [%d]: %s is calling cn wavefile, !!!!!!!! file_match_str=%s \n",ied->id,ied->name,file_match_str);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s开始召唤录波文件", LD_info->name,LD_info->mp_id);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【NORMAL】监测点:%s - id:%s开始召唤录波文件", LD_info->name,LD_info->mp_id);
|
||||||
|
|
||||||
ret = SD_FAILURE;
|
ret = SD_FAILURE;
|
||||||
filenum = 0;
|
filenum = 0;
|
||||||
@@ -1880,14 +2011,17 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
int ret2,ret3;
|
int ret2,ret3;
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s获取录波文件列表成功,开始匹配录波文件", LD_info->name,LD_info->mp_id);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【NORMAL】监测点:%s - id:%s获取录波文件列表成功,开始匹配录波文件", LD_info->name,LD_info->mp_id);
|
||||||
|
|
||||||
//WW 2023-11-01将录波段号由字符串匹配修改为int的fltnum匹配
|
//WW 2023-11-01将录波段号由字符串匹配修改为int的fltnum匹配
|
||||||
ret2 = parse_file_names_by_fltnum(LD_info->FltNum[i], ldstr, filenames, filenum, &cfg_idx, &dat_idx, file_base_name, file_yyyymm);
|
ret2 = parse_file_names_by_fltnum(LD_info->FltNum[i], ldstr, filenames, filenum, &cfg_idx, &dat_idx, file_base_name, file_yyyymm);
|
||||||
//WW 2023-11-01 end
|
//WW 2023-11-01 end
|
||||||
if (ret2 !=APR_SUCCESS){
|
if (ret2 !=APR_SUCCESS){
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s匹配录波文件失败", LD_info->name,LD_info->mp_id);
|
//DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【WARN】监测点:%s - id:%s前置记录的录波事件上传的录波号段%d与从装置获取的录波文件列表匹配失败,装置没有对应的号段的录波文件,清除该记录", LD_info->name,LD_info->mp_id,LD_info->FltNum[i]);
|
||||||
|
//lnk20250819装置没有对应的文件时清除录波号段
|
||||||
|
printf("监测点:%s - id:%s前置记录的录波事件上传的录波号段%d与从装置获取的录波文件列表匹配失败,装置没有对应的号段的录波文件,清除该记录", LD_info->name,LD_info->mp_id,LD_info->FltNum[i]);
|
||||||
|
LD_info->FltNum[i] = -1;
|
||||||
return ret2;
|
return ret2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1900,15 +2034,35 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
if (ret2==SD_SUCCESS && ret3==SD_SUCCESS ) { //两个文件都写好了
|
if (ret2==SD_SUCCESS && ret3==SD_SUCCESS ) { //两个文件都写好了
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s从终端获取录波文件成功", LD_info->name,LD_info->mp_id);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【NORMAL】监测点:%s - id:%s从终端获取录波文件成功", LD_info->name,LD_info->mp_id);
|
||||||
|
|
||||||
QVVR_t *qvvr; //暂态事件
|
QVVR_t *qvvr; //暂态事件
|
||||||
long long start_tm,trig_tm,end_tm;
|
long long start_tm,trig_tm,end_tm;//北京时间
|
||||||
|
|
||||||
ret2 = extract_timestamp_from_cfg_file(filenames[cfg_idx],&start_tm,&trig_tm);//提取文件的开始时间和触发时间
|
ret2 = extract_timestamp_from_cfg_file(filenames[cfg_idx],&start_tm,&trig_tm);//提取文件的开始时间和触发时间
|
||||||
|
|
||||||
|
//添加录波文件时间戳校准20260409
|
||||||
|
{
|
||||||
|
XmlConfigC cfg;
|
||||||
|
long long utc_or_beijing = 0;
|
||||||
|
if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg)) {
|
||||||
|
if(strcmp(cfg.WaveTimeFlag, "utc") == 0){//装置时间是utc还是北京
|
||||||
|
utc_or_beijing = 28800000;//八小时相差毫秒数
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
utc_or_beijing = 0;
|
||||||
|
}
|
||||||
|
trig_tm = trig_tm + utc_or_beijing;//如果是utc时间则转换为北京时间
|
||||||
|
start_tm = start_tm + utc_or_beijing;//接口上送没用到
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("读取失败,未找到 dev_type\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf(">>>>>>>> extract_timestamp_from_cfg_file end \n");
|
printf(">>>>>>>> extract_timestamp_from_cfg_file end \n");
|
||||||
if (ret2 ==APR_SUCCESS) {
|
if (ret2 ==APR_SUCCESS) {
|
||||||
DIY_INFOLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s提取录波文件时间成功", LD_info->name,LD_info->mp_id);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【NORMAL】监测点:%s - id:%s提取录波文件时间成功", LD_info->name,LD_info->mp_id);
|
||||||
//to find the paired qvvr by the time of trig_tm
|
//to find the paired qvvr by the time of trig_tm
|
||||||
printf(">>>>>>>> extract_timestamp_from_cfg_file success \n");
|
printf(">>>>>>>> extract_timestamp_from_cfg_file success \n");
|
||||||
qvvr = find_qvvr_by_trig_tm(LD_info,trig_tm); //根据文件的触发时间查找检测点记录的匹配上的暂态事件
|
qvvr = find_qvvr_by_trig_tm(LD_info,trig_tm); //根据文件的触发时间查找检测点记录的匹配上的暂态事件
|
||||||
@@ -1928,18 +2082,18 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
|
|
||||||
char loc_file_fullname_cfg[256];//本地文件名
|
char loc_file_fullname_cfg[256];//本地文件名
|
||||||
memset(loc_file_fullname_cfg, 0, sizeof(loc_file_fullname_cfg));
|
memset(loc_file_fullname_cfg, 0, sizeof(loc_file_fullname_cfg));
|
||||||
apr_snprintf(loc_file_fullname_cfg, sizeof(loc_file_fullname_cfg), "/home/pq/FeProject/comtrade/%s", cfg_only_filename_ret);
|
apr_snprintf(loc_file_fullname_cfg, sizeof(loc_file_fullname_cfg), "/FeProject/comtrade/%s", cfg_only_filename_ret);
|
||||||
char oss_file_fullname_cfg[256];//远端文件名
|
char oss_file_fullname_cfg[256];//远端文件名
|
||||||
memset(oss_file_fullname_cfg, 0, sizeof(oss_file_fullname_cfg));
|
memset(oss_file_fullname_cfg, 0, sizeof(oss_file_fullname_cfg));
|
||||||
apr_snprintf(oss_file_fullname_cfg, sizeof(oss_file_fullname_cfg), "comtrade/wave/%s/%s", LD_info->mp_id, cfg_only_filename_ret);
|
apr_snprintf(oss_file_fullname_cfg, sizeof(oss_file_fullname_cfg), "comtrade/wave/%s/%s", LD_info->mp_id, cfg_only_filename_ret);
|
||||||
if (FILE_FLAG == 1) {
|
if (FILE_FLAG == 1) {
|
||||||
PutOSS(oss_file_fullname_cfg, loc_file_fullname_cfg);//使用buffer推送文件
|
//PutOSS(oss_file_fullname_cfg, loc_file_fullname_cfg);//使用buffer推送文件
|
||||||
}
|
}
|
||||||
else if (FILE_FLAG == 2) {
|
else if (FILE_FLAG == 2) {
|
||||||
OBSFile(loc_file_fullname_cfg, oss_file_fullname_cfg, "putObject");//这里并没有上传文件流
|
//OBSFile(loc_file_fullname_cfg, oss_file_fullname_cfg, "putObject");//这里并没有上传文件流
|
||||||
}
|
}
|
||||||
else if(FILE_FLAG==3){
|
else if(FILE_FLAG==3){
|
||||||
WebAPI_Uds_Upload(UDS_UPLOAD_URL, loc_file_fullname_cfg, uuid_cfg, filename_cfg);//通过form-data上传文件
|
//WebAPI_Uds_Upload(UDS_UPLOAD_URL, loc_file_fullname_cfg, uuid_cfg, filename_cfg);//通过form-data上传文件
|
||||||
}
|
}
|
||||||
//LNK20241031使用JSON编码文件上传-具体的远端路径可以用原本代码的硬编码或者在配置文件中获取
|
//LNK20241031使用JSON编码文件上传-具体的远端路径可以用原本代码的硬编码或者在配置文件中获取
|
||||||
else if (FILE_FLAG == 4) {
|
else if (FILE_FLAG == 4) {
|
||||||
@@ -1966,18 +2120,18 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
|
|
||||||
char loc_file_fullname_dat[256];
|
char loc_file_fullname_dat[256];
|
||||||
memset(loc_file_fullname_dat, 0, sizeof(loc_file_fullname_dat));
|
memset(loc_file_fullname_dat, 0, sizeof(loc_file_fullname_dat));
|
||||||
apr_snprintf(loc_file_fullname_dat, sizeof(loc_file_fullname_dat), "/home/pq/FeProject/comtrade/%s", dat_only_filename_ret);
|
apr_snprintf(loc_file_fullname_dat, sizeof(loc_file_fullname_dat), "/FeProject/comtrade/%s", dat_only_filename_ret);
|
||||||
char oss_file_fullname_dat[256];
|
char oss_file_fullname_dat[256];
|
||||||
memset(oss_file_fullname_dat, 0, sizeof(oss_file_fullname_dat));
|
memset(oss_file_fullname_dat, 0, sizeof(oss_file_fullname_dat));
|
||||||
apr_snprintf(oss_file_fullname_dat, sizeof(oss_file_fullname_dat), "comtrade/wave/%s/%s", LD_info->mp_id, dat_only_filename_ret);
|
apr_snprintf(oss_file_fullname_dat, sizeof(oss_file_fullname_dat), "comtrade/wave/%s/%s", LD_info->mp_id, dat_only_filename_ret);
|
||||||
if (FILE_FLAG == 1) {
|
if (FILE_FLAG == 1) {
|
||||||
PutOSS(oss_file_fullname_dat, loc_file_fullname_dat);//使用buffer推送文件
|
//PutOSS(oss_file_fullname_dat, loc_file_fullname_dat);//使用buffer推送文件
|
||||||
}
|
}
|
||||||
else if (FILE_FLAG == 2) {
|
else if (FILE_FLAG == 2) {
|
||||||
OBSFile(loc_file_fullname_dat, oss_file_fullname_dat, "putObject");//这里并没有上传文件流
|
//OBSFile(loc_file_fullname_dat, oss_file_fullname_dat, "putObject");//这里并没有上传文件流
|
||||||
}
|
}
|
||||||
else if(FILE_FLAG==3){
|
else if(FILE_FLAG==3){
|
||||||
WebAPI_Uds_Upload(UDS_UPLOAD_URL, loc_file_fullname_dat, uuid_dat, filename_dat);//通过form-data上传文件
|
//WebAPI_Uds_Upload(UDS_UPLOAD_URL, loc_file_fullname_dat, uuid_dat, filename_dat);//通过form-data上传文件
|
||||||
}
|
}
|
||||||
//LNK20241031使用JSON编码文件上传-具体的远端路径可以用原本代码的硬编码或者在配置文件中获取
|
//LNK20241031使用JSON编码文件上传-具体的远端路径可以用原本代码的硬编码或者在配置文件中获取
|
||||||
else if (FILE_FLAG == 4) {
|
else if (FILE_FLAG == 4) {
|
||||||
@@ -2120,20 +2274,38 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if(ld_has_qvvr_nonempty(LD_info))//防止手动录波日志还一直上送
|
||||||
{
|
{
|
||||||
DIY_ERRORLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s匹配录波文件失败,请检查装置的暂态时间是秒还是毫秒,并修改映射文件", LD_info->name,LD_info->mp_id);
|
//获取时间类型lnk20250520
|
||||||
|
XmlConfigC cfg;
|
||||||
|
if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg)) {
|
||||||
|
if(strcmp(cfg.UnitOfTimeUnit, "1") == 0){//持续时间上送的是秒1还是毫秒0
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【ERROR】监测点:%s - id:%s 匹配录波文件失败,录波号段:%d,录波文件的开始时间:%lld,触发时间:%lld,映射配置的暂态持续时间单位是s", LD_info->name,LD_info->mp_id,LD_info->FltNum[i],start_tm,trig_tm);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【ERROR】监测点:%s - id:%s 匹配录波文件失败,录波号段:%d,录波文件的开始时间:%lld,触发时间:%lld,映射配置的暂态持续时间单位是ms", LD_info->name,LD_info->mp_id,LD_info->FltNum[i],start_tm,trig_tm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("读取失败,未找到 dev_type\n");
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【ERROR】监测点:%s - id:%s 匹配录波文件失败,录波号段:%d,录波文件的开始时间:%lld,触发时间:%lld,映射配置的暂态持续时间单位未配置", LD_info->name,LD_info->mp_id,LD_info->FltNum[i],start_tm,trig_tm);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【ERROR】监测点:%s - id:%s 下载录波文件%s和%s失败,录波号段:%d", LD_info->name,LD_info->mp_id,filenames[cfg_idx],filenames[dat_idx],LD_info->FltNum[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ied && chnl_usr){
|
if (ied && chnl_usr){
|
||||||
echo_warn2("mms_mvla_fdir Failed: IED [%d] %s \n", ied->id , chnl_usr->ip_str) ;
|
echo_warn2("mms_mvla_fdir Failed: IED [%d] %s \n", ied->id , chnl_usr->ip_str) ;
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s召唤录波文件失败", LD_info->name,LD_info->mp_id);
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_COMTRADE_FILE,"【WARN】监测点:%s - id:%s召唤录波文件列表失败,放弃这个号段", LD_info->name,LD_info->mp_id);
|
||||||
|
LD_info->FltNum[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return APR_EAGAIN;
|
return APR_EAGAIN;
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
|||||||
|
|
||||||
extern pt61850app_t* g_pt61850app;
|
extern pt61850app_t* g_pt61850app;
|
||||||
|
|
||||||
|
extern bool DEBUGOPEN;
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Static function prototypes. */
|
/* Static function prototypes. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
@@ -126,7 +128,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
|
|||||||
|
|
||||||
double start, end;
|
double start, end;
|
||||||
static double last_check_recall_config_time = 0.0;
|
static double last_check_recall_config_time = 0.0;
|
||||||
printf("\nbrf for");
|
if(DEBUGOPEN)printf("\nbrf for");
|
||||||
for (j = 0; j < jou_entry->ef.data.num_of_var; j++) {
|
for (j = 0; j < jou_entry->ef.data.num_of_var; j++) {
|
||||||
|
|
||||||
printf("\nfor %d", jou_entry->ef.data.num_of_var);
|
printf("\nfor %d", jou_entry->ef.data.num_of_var);
|
||||||
@@ -146,7 +148,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
|
|||||||
do_name++;
|
do_name++;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nbrf if");
|
if(DEBUGOPEN)printf("\nbrf if");
|
||||||
if (sel_mvl_type_ctrl_flag(do_name) == -1)
|
if (sel_mvl_type_ctrl_flag(do_name) == -1)
|
||||||
{
|
{
|
||||||
var_type_id = mms_var_type_id_create(clientNetInfo, DOM_SPEC,
|
var_type_id = mms_var_type_id_create(clientNetInfo, DOM_SPEC,
|
||||||
@@ -157,15 +159,15 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
|
|||||||
add_mvl_type_ctrl(doname, var_type_id);
|
add_mvl_type_ctrl(doname, var_type_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\nbrf var_type_id");
|
if(DEBUGOPEN)printf("\nbrf var_type_id");
|
||||||
var_type_id = sel_mvl_type_ctrl_flag(do_name);
|
var_type_id = sel_mvl_type_ctrl_flag(do_name);
|
||||||
printf("\nafter var_type_id");
|
if(DEBUGOPEN)printf("\nafter var_type_id");
|
||||||
|
|
||||||
if (var_type_id < 0) {
|
if (var_type_id < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log_var_jou_data(var_type_id,&(jou_entry->ef.data.list_of_var[j].value_spec),&mms_dec_data, do_name);
|
log_var_jou_data(var_type_id,&(jou_entry->ef.data.list_of_var[j].value_spec),&mms_dec_data, do_name);
|
||||||
printf("\nafter log_var_jou_data");
|
if(DEBUGOPEN)printf("\nafter log_var_jou_data");
|
||||||
if (timeflag) {
|
if (timeflag) {
|
||||||
int readtime = 0;
|
int readtime = 0;
|
||||||
int readquailty = 0;
|
int readquailty = 0;
|
||||||
@@ -443,7 +445,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\naft for");
|
if(DEBUGOPEN)printf("\naft for");
|
||||||
if ( log_data_type == QVVR_DATA ) {
|
if ( log_data_type == QVVR_DATA ) {
|
||||||
processQVVR_end(loginfo->LD_info);
|
processQVVR_end(loginfo->LD_info);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -854,15 +854,8 @@ ST_VOID u_iec_rpt_ind_data_by_devtype(MVL_VAR_ASSOC** info_va,
|
|||||||
printf("[BEGIND Process] Received Report From %s:%d %s %s ,va_total = %i ,【count = %i】 \n",
|
printf("[BEGIND Process] Received Report From %s:%d %s %s ,va_total = %i ,【count = %i】 \n",
|
||||||
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
|
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", LD_info->mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", LD_info->mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_d,"【NORMAL】前置收到监测点:%s - id:%s的报告,报告名称:%s,监测点对应终端的ip和端口是: %s:%d,报告总数:%i,当前报告数:%i", LD_info->name,LD_info->mp_id,rcb_info->RptID,chnl_usr->ip_str,chnl_usr->chnl->port,va_total, rptinfo->count);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】前置收到监测点:%s - id:%s的报告,报告名称:%s,监测点对应终端的ip和端口是: %s:%d,报告总数:%i,当前报告数:%i", LD_info->name,LD_info->mp_id,rcb_info->RptID,chnl_usr->ip_str,chnl_usr->chnl->port,va_total, rptinfo->count);
|
||||||
|
|
||||||
//apr_time_t previousTime = apr_time_now();//
|
//apr_time_t previousTime = apr_time_now();//
|
||||||
//apr_time_exp_t localTime;
|
//apr_time_exp_t localTime;
|
||||||
@@ -1162,14 +1155,14 @@ ST_VOID u_iec_rpt_ind_data_by_devtype(MVL_VAR_ASSOC** info_va,
|
|||||||
echo_err3("Ignore this report due to line_id invalid , Report From %s %s %s !!!",
|
echo_err3("Ignore this report due to line_id invalid , Report From %s %s %s !!!",
|
||||||
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID);
|
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID);
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_ERRORLOG(full_key_m_d,"【ERROR】前置不处理这个监测点:%s - id:%s的报告,报告名称:%s,原因是监测点的序号非法", LD_info->name,LD_info->mp_id,rcb_info->RptID);
|
DIY_ERRORLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【ERROR】前置不处理这个监测点:%s - id:%s的报告,报告名称:%s,原因是监测点的序号非法", LD_info->name,LD_info->mp_id,rcb_info->RptID);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("[END Process] Report From %s:%d %s %s ,va_total = %i ,【count = %i】 \n",
|
printf("[END Process] Report From %s:%d %s %s ,va_total = %i ,【count = %i】 \n",
|
||||||
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
|
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
|
||||||
|
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_INFOLOG(full_key_m_d,"【NORMAL】前置处理监测点:%s - id:%s的报告结束,报告名称:%s,监测点对应终端的ip和端口是: %s:%d,报告总数:%i,当前报告数:%i", LD_info->name,LD_info->mp_id,rcb_info->RptID,chnl_usr->ip_str,chnl_usr->chnl->port,va_total, rptinfo->count);
|
DIY_INFOLOG_CODE(LD_info->mp_id,2,LOG_CODE_REPORT,"【NORMAL】前置处理监测点:%s - id:%s的报告结束,报告名称:%s,监测点对应终端的ip和端口是: %s:%d,报告总数:%i,当前报告数:%i", LD_info->name,LD_info->mp_id,rcb_info->RptID,chnl_usr->ip_str,chnl_usr->chnl->port,va_total, rptinfo->count);
|
||||||
|
|
||||||
//apr_time_t previousTimeend = apr_time_now();//
|
//apr_time_t previousTimeend = apr_time_now();//
|
||||||
//apr_time_exp_t localTimeend;
|
//apr_time_exp_t localTimeend;
|
||||||
@@ -1462,7 +1455,7 @@ ST_VOID u_iec_rpt_ind_data(MVL_VAR_ASSOC** info_va,
|
|||||||
//need do nothing!
|
//need do nothing!
|
||||||
not_set_rpt_q_this = FALSE;
|
not_set_rpt_q_this = FALSE;
|
||||||
}
|
}
|
||||||
else if (strstr(FULL_FCDA_Name, "GGIO"))
|
else if (strstr(FULL_FCDA_Name, "GGIO") || strstr(FULL_FCDA_Name, "LPHD"))
|
||||||
{
|
{
|
||||||
not_set_rpt_q_this = FALSE;
|
not_set_rpt_q_this = FALSE;
|
||||||
}
|
}
|
||||||
@@ -1485,7 +1478,7 @@ ST_VOID u_iec_rpt_ind_data(MVL_VAR_ASSOC** info_va,
|
|||||||
//need do nothing!
|
//need do nothing!
|
||||||
not_set_rpt_TimeID_this = FALSE;
|
not_set_rpt_TimeID_this = FALSE;
|
||||||
}
|
}
|
||||||
else if (strstr(FULL_FCDA_Name, "GGIO")) {//CZY 2023-08-17 WW 2022-11-14修改判断 LLN0$BR$brcbRDRE
|
else if (strstr(FULL_FCDA_Name, "GGIO") || strstr(FULL_FCDA_Name, "LPHD")) {//CZY 2023-08-17 WW 2022-11-14修改判断 LLN0$BR$brcbRDRE
|
||||||
//need do nothing!
|
//need do nothing!
|
||||||
not_set_rpt_TimeID_this = FALSE;
|
not_set_rpt_TimeID_this = FALSE;
|
||||||
}
|
}
|
||||||
@@ -1532,7 +1525,7 @@ ST_VOID u_iec_rpt_ind_data(MVL_VAR_ASSOC** info_va,
|
|||||||
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 修改判断LLN0$BR$brcbRDRE
|
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 修改判断LLN0$BR$brcbRDRE
|
||||||
processRDRE_data(LD_info, FULL_FCDA_Name, v);
|
processRDRE_data(LD_info, FULL_FCDA_Name, v);
|
||||||
}
|
}
|
||||||
else if (strstr(FULL_FCDA_Name, "GGIO"))
|
else if (strstr(FULL_FCDA_Name, "GGIO") || strstr(FULL_FCDA_Name, "LPHD"))
|
||||||
{
|
{
|
||||||
ied_t* ied = LD_info->ied;
|
ied_t* ied = LD_info->ied;
|
||||||
ied_usr_t* ied_usr = GET_IEDEXT_ADDR(ied);
|
ied_usr_t* ied_usr = GET_IEDEXT_ADDR(ied);
|
||||||
|
|||||||
571
mms/mmsclient.c
571
mms/mmsclient.c
@@ -80,6 +80,9 @@
|
|||||||
|
|
||||||
#include <ctype.h> //lnk20241119
|
#include <ctype.h> //lnk20241119
|
||||||
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
||||||
|
|
||||||
|
#include "../log4cplus/log4.h"
|
||||||
|
|
||||||
extern uint32_t g_node_id;
|
extern uint32_t g_node_id;
|
||||||
extern char subdir[128];
|
extern char subdir[128];
|
||||||
unsigned int g_no_auth = 0;
|
unsigned int g_no_auth = 0;
|
||||||
@@ -132,6 +135,8 @@ IDENT_RESP_INFO identify_response_info =
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
extern pt61850app_t *g_pt61850app;
|
||||||
|
|
||||||
extern TP0_CONN *tp0_conn_arr; /* ptr to array of "max_num_conns" structs */
|
extern TP0_CONN *tp0_conn_arr; /* ptr to array of "max_num_conns" structs */
|
||||||
|
|
||||||
static ST_VOID disc_ind_fun (MVL_NET_INFO *cc, ST_INT discType);
|
static ST_VOID disc_ind_fun (MVL_NET_INFO *cc, ST_INT discType);
|
||||||
@@ -269,12 +274,25 @@ MY_CONTROL_INFO my_control_info;
|
|||||||
ST_INT mms_var_type_id_create (MVL_NET_INFO *clientNetInfo, ST_INT scope,
|
ST_INT mms_var_type_id_create (MVL_NET_INFO *clientNetInfo, ST_INT scope,
|
||||||
ST_CHAR *dom_name, ST_CHAR *var_name, int iTimeOut)
|
ST_CHAR *dom_name, ST_CHAR *var_name, int iTimeOut)
|
||||||
{
|
{
|
||||||
MVL_REQ_PEND *reqCtrl;
|
//MVL_REQ_PEND *reqCtrl;
|
||||||
|
//reqCtrl 必须初始化为 NULL,防止 mvla_getvar 失败后释放野指针
|
||||||
|
MVL_REQ_PEND *reqCtrl = NULL;
|
||||||
|
|
||||||
GETVAR_REQ_INFO getvar_req;
|
GETVAR_REQ_INFO getvar_req;
|
||||||
ST_INT type_id = -1; /* start with invalid type id */
|
ST_INT type_id = -1; /* start with invalid type id */
|
||||||
ST_RET ret;
|
ST_RET ret;
|
||||||
|
|
||||||
|
//参数合法性检查
|
||||||
|
if (clientNetInfo == NULL || dom_name == NULL || var_name == NULL)
|
||||||
|
{
|
||||||
|
printf("[GETVAR] invalid arg netInfo=%p dom=%p var=%p\n",
|
||||||
|
clientNetInfo, dom_name, var_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构体清零,避免未初始化字段导致异常
|
||||||
|
memset(&getvar_req, 0, sizeof(getvar_req));
|
||||||
|
|
||||||
/* Get the type of this "Oper" attribute & create type. */
|
/* Get the type of this "Oper" attribute & create type. */
|
||||||
/* Would be more efficient to do this just once before this function.*/
|
/* Would be more efficient to do this just once before this function.*/
|
||||||
getvar_req.req_tag = GETVAR_NAME;
|
getvar_req.req_tag = GETVAR_NAME;
|
||||||
@@ -283,19 +301,53 @@ ST_RET ret;
|
|||||||
if (scope == DOM_SPEC)
|
if (scope == DOM_SPEC)
|
||||||
getvar_req.name.domain_id= dom_name;
|
getvar_req.name.domain_id= dom_name;
|
||||||
getvar_req.name.obj_name.vmd_spec = var_name;
|
getvar_req.name.obj_name.vmd_spec = var_name;
|
||||||
|
|
||||||
|
//增加调试打印,确认崩溃点
|
||||||
|
printf("[GETVAR] start dom=%s var=%s\n", dom_name, var_name);
|
||||||
|
|
||||||
ret = mvla_getvar (clientNetInfo, &getvar_req, &reqCtrl);
|
ret = mvla_getvar (clientNetInfo, &getvar_req, &reqCtrl);
|
||||||
if (ret == SD_SUCCESS)
|
|
||||||
|
//打印 mvla_getvar 返回值和 reqCtrl
|
||||||
|
printf("[GETVAR] mvla_getvar ret=0x%X reqCtrl=%p\n", ret, reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS){
|
||||||
ret = waitReqDone (reqCtrl, iTimeOut);
|
ret = waitReqDone (reqCtrl, iTimeOut);
|
||||||
if (ret != SD_SUCCESS)
|
//打印 waitReqDone 返回值
|
||||||
|
printf("[GETVAR] wait ret=0x%X\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != SD_SUCCESS){
|
||||||
echo_warn2 ("Error getting type of variable '%s' in domain '%s'\n", var_name, dom_name);
|
echo_warn2 ("Error getting type of variable '%s' in domain '%s'\n", var_name, dom_name);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Don't care about name so pass NULL. */
|
/* Don't care about name so pass NULL. */
|
||||||
type_id = mvl_type_id_create (NULL, reqCtrl->u.getvar.resp_info->type_spec.data,
|
//type_id = mvl_type_id_create (NULL, reqCtrl->u.getvar.resp_info->type_spec.data,
|
||||||
reqCtrl->u.getvar.resp_info->type_spec.len);
|
// reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
//严格检查 resp_info/type_spec,避免空指针崩溃
|
||||||
|
if (ret == SD_SUCCESS &&
|
||||||
|
reqCtrl != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.data != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len > 0)
|
||||||
|
{
|
||||||
|
type_id = mvl_type_id_create(
|
||||||
|
NULL,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.data,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
|
||||||
|
printf("[GETVAR] create type_id=%d len=%d\n",
|
||||||
|
type_id,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("[GETVAR] failed dom=%s var=%s ret=0x%X\n",
|
||||||
|
dom_name, var_name, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mvl_free_req_ctrl (reqCtrl); /* Done with request struct */
|
//只有 reqCtrl 非空才释放
|
||||||
|
if (reqCtrl != NULL)mvl_free_req_ctrl (reqCtrl); /* Done with request struct */
|
||||||
return (type_id);
|
return (type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1457,6 +1509,29 @@ ST_VOID u_mvl_ident_ind (MVL_IND_PEND *indCtrl)
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* getFile */
|
/* getFile */
|
||||||
|
/*
|
||||||
|
先向远端发 fopen,打开远程文件
|
||||||
|
|
||||||
|
拿到这个远程文件会话句柄 frsmid
|
||||||
|
|
||||||
|
循环发 fread,一块一块把远程文件内容读回来并写入本地文件
|
||||||
|
|
||||||
|
最后发 fclose,关闭远程文件
|
||||||
|
|
||||||
|
clientNetInfo:客户端和 MMS 服务器之间的网络连接信息
|
||||||
|
|
||||||
|
loc_file:本地保存的文件路径
|
||||||
|
|
||||||
|
rem_file:远端设备上的文件路径
|
||||||
|
|
||||||
|
iTimeout:每次请求等待响应的超时时间
|
||||||
|
|
||||||
|
返回值:
|
||||||
|
|
||||||
|
SD_SUCCESS:下载成功
|
||||||
|
|
||||||
|
其他:失败错误码
|
||||||
|
*/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_RET mms_getFile (MVL_NET_INFO *clientNetInfo, ST_CHAR *loc_file,
|
ST_RET mms_getFile (MVL_NET_INFO *clientNetInfo, ST_CHAR *loc_file,
|
||||||
ST_CHAR *rem_file, ST_INT iTimeout)
|
ST_CHAR *rem_file, ST_INT iTimeout)
|
||||||
@@ -1523,6 +1598,59 @@ ERR:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//***************************lnk20260309下发文件到装置*********************/
|
||||||
|
ST_RET mms_putFile(MVL_NET_INFO *clientNetInfo,
|
||||||
|
ST_CHAR *src_file,
|
||||||
|
ST_CHAR *dest_file,
|
||||||
|
ST_INT iTimeout)
|
||||||
|
{
|
||||||
|
MVL_REQ_PEND *reqCtrl = NULL;
|
||||||
|
ST_RET ret = SD_FAILURE;
|
||||||
|
|
||||||
|
if (clientNetInfo == NULL)
|
||||||
|
{
|
||||||
|
printf("\n mms_putFile failed: clientNetInfo is NULL");
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_file == NULL || src_file[0] == '\0')
|
||||||
|
{
|
||||||
|
printf("\n mms_putFile failed: src_file is NULL or empty");
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest_file == NULL || dest_file[0] == '\0')
|
||||||
|
{
|
||||||
|
printf("\n mms_putFile failed: dest_file is NULL or empty");
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mvla_obtfile(clientNetInfo, src_file, dest_file, &reqCtrl);
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
ret = waitReqDone(reqCtrl, iTimeout);
|
||||||
|
|
||||||
|
if (ret != SD_SUCCESS)
|
||||||
|
{
|
||||||
|
printf("\n mms_putFile failed, src='%s', dest='%s', ret=0x%X",
|
||||||
|
src_file, dest_file, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\n mms_putFile OK, src='%s', dest='%s'",
|
||||||
|
src_file, dest_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqCtrl != NULL)
|
||||||
|
{
|
||||||
|
mvl_free_req_ctrl(reqCtrl);
|
||||||
|
reqCtrl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//************************************************************************/
|
||||||
|
/* putFile */
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* init_mem */
|
/* init_mem */
|
||||||
@@ -1607,20 +1735,20 @@ static ST_VOID *my_realloc_err (ST_VOID *old, ST_UINT size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//#define MAX_FILE_HANDLE_NUM (256)
|
#define MAX_FILE_HANDLE_NUM (256)
|
||||||
//static FILE *fp_arr[MAX_FILE_HANDLE_NUM];
|
static FILE *fp_arr[MAX_FILE_HANDLE_NUM];
|
||||||
//static ST_INT32 cur_handle = 0;
|
static ST_INT32 cur_handle = 0;
|
||||||
//ST_INT32 set_file_pointer( FILE *fp)
|
ST_INT32 set_file_pointer( FILE *fp)
|
||||||
//{
|
{
|
||||||
// ST_INT32 the_handle = cur_handle;
|
ST_INT32 the_handle = cur_handle;
|
||||||
// fp_arr[cur_handle++] = fp;
|
fp_arr[cur_handle++] = fp;
|
||||||
// cur_handle %= MAX_FILE_HANDLE_NUM;
|
cur_handle %= MAX_FILE_HANDLE_NUM;
|
||||||
// return the_handle;
|
return the_handle;
|
||||||
//}
|
}
|
||||||
//FILE* get_file_pointer(ST_INT32 handle)
|
FILE* get_file_pointer(ST_INT32 handle)
|
||||||
//{
|
{
|
||||||
// return fp_arr[handle];
|
return fp_arr[handle];
|
||||||
//}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if (MMS_FOPEN_EN & RESP_EN)
|
#if (MMS_FOPEN_EN & RESP_EN)
|
||||||
@@ -1629,39 +1757,39 @@ static ST_VOID *my_realloc_err (ST_VOID *old, ST_UINT size)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//FOPEN_RESP_INFO resp_info;
|
FOPEN_RESP_INFO resp_info;
|
||||||
//struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
|
||||||
//fp = fopen (indCtrl->u.fopen.filename, "rb"); /* CRITICAL: use "b" flag for binary transfer*/
|
fp = fopen (indCtrl->u.fopen.filename, "rb"); /* CRITICAL: use "b" flag for binary transfer*/
|
||||||
//if (fp == NULL)
|
if (fp == NULL)
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl,11,6); /* File-access denied */
|
_mplas_err_resp (indCtrl,11,6); /* File-access denied */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//if (fseek (fp, indCtrl->u.fopen.init_pos, SEEK_SET))
|
if (fseek (fp, indCtrl->u.fopen.init_pos, SEEK_SET))
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl,11,5); /* Position invalid */
|
_mplas_err_resp (indCtrl,11,5); /* Position invalid */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
///* WARNING: this only works if (FILE *) is a 32-bit pointer. */
|
/* WARNING: this only works if (FILE *) is a 32-bit pointer. */
|
||||||
//resp_info.frsmid = set_file_pointer(fp); //(ST_INT32) fp;
|
resp_info.frsmid = set_file_pointer(fp); //(ST_INT32) fp;
|
||||||
|
|
||||||
//if (fstat (fileno (fp), &stat_buf))
|
if (fstat (fileno (fp), &stat_buf))
|
||||||
// { /* Can't get file size or time */
|
{ /* Can't get file size or time */
|
||||||
// _mplas_err_resp (indCtrl,11,0); /* File Problem, Other */
|
_mplas_err_resp (indCtrl,11,0); /* File Problem, Other */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//else
|
else
|
||||||
// {
|
{
|
||||||
// resp_info.ent.fsize = stat_buf.st_size;
|
resp_info.ent.fsize = stat_buf.st_size;
|
||||||
// resp_info.ent.mtimpres = SD_TRUE;
|
resp_info.ent.mtimpres = SD_TRUE;
|
||||||
// resp_info.ent.mtime = stat_buf.st_mtime;
|
resp_info.ent.mtime = stat_buf.st_mtime;
|
||||||
// }
|
}
|
||||||
|
|
||||||
//indCtrl->u.fopen.resp_info = &resp_info;
|
indCtrl->u.fopen.resp_info = &resp_info;
|
||||||
//mplas_fopen_resp (indCtrl);
|
mplas_fopen_resp (indCtrl);
|
||||||
}
|
}
|
||||||
#endif /* MMS_FOPEN_EN & RESP_EN */
|
#endif /* MMS_FOPEN_EN & RESP_EN */
|
||||||
|
|
||||||
@@ -1672,31 +1800,31 @@ ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//ST_UCHAR *tmp_buf;
|
ST_UCHAR *tmp_buf;
|
||||||
//MVLAS_FREAD_CTRL *fread_ctrl = &indCtrl->u.fread;
|
MVLAS_FREAD_CTRL *fread_ctrl = &indCtrl->u.fread;
|
||||||
//FREAD_RESP_INFO resp_info;
|
FREAD_RESP_INFO resp_info;
|
||||||
|
|
||||||
//fp = get_file_pointer(fread_ctrl->req_info->frsmid);// (FILE *) fread_ctrl->req_info->frsmid;
|
fp = get_file_pointer(fread_ctrl->req_info->frsmid);// (FILE *) fread_ctrl->req_info->frsmid;
|
||||||
///* Do NOT read more than "max_size". */
|
/* Do NOT read more than "max_size". */
|
||||||
//tmp_buf = (ST_UCHAR *) chk_malloc (fread_ctrl->max_size);
|
tmp_buf = (ST_UCHAR *) chk_malloc (fread_ctrl->max_size);
|
||||||
|
|
||||||
//resp_info.fd_len = fread (tmp_buf, 1, fread_ctrl->max_size, fp);
|
resp_info.fd_len = fread (tmp_buf, 1, fread_ctrl->max_size, fp);
|
||||||
//if (resp_info.fd_len == 0 && ferror (fp))
|
if (resp_info.fd_len == 0 && ferror (fp))
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl, 3, 0);
|
_mplas_err_resp (indCtrl, 3, 0);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
//resp_info.filedata = tmp_buf;
|
resp_info.filedata = tmp_buf;
|
||||||
//if (resp_info.fd_len == fread_ctrl->max_size)
|
if (resp_info.fd_len == fread_ctrl->max_size)
|
||||||
// resp_info.more_follows = SD_TRUE;
|
resp_info.more_follows = SD_TRUE;
|
||||||
//else
|
else
|
||||||
// resp_info.more_follows = SD_FALSE;
|
resp_info.more_follows = SD_FALSE;
|
||||||
|
|
||||||
//fread_ctrl->resp_info = &resp_info;
|
fread_ctrl->resp_info = &resp_info;
|
||||||
//mplas_fread_resp (indCtrl);
|
mplas_fread_resp (indCtrl);
|
||||||
//chk_free (tmp_buf); /* Temporary buffer */
|
chk_free (tmp_buf); /* Temporary buffer */
|
||||||
}
|
}
|
||||||
#endif /* #if (MMS_FREAD_EN & RESP_EN) */
|
#endif /* #if (MMS_FREAD_EN & RESP_EN) */
|
||||||
|
|
||||||
@@ -1706,15 +1834,15 @@ ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fclose_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fclose_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//MVLAS_FCLOSE_CTRL *fclose_ctrl = &indCtrl->u.fclose;
|
MVLAS_FCLOSE_CTRL *fclose_ctrl = &indCtrl->u.fclose;
|
||||||
|
|
||||||
//fp = get_file_pointer(fclose_ctrl->req_info->frsmid);//(FILE *) fclose_ctrl->req_info->frsmid;
|
fp = get_file_pointer(fclose_ctrl->req_info->frsmid);//(FILE *) fclose_ctrl->req_info->frsmid;
|
||||||
|
|
||||||
//if (fclose (fp))
|
if (fclose (fp))
|
||||||
// _mplas_err_resp (indCtrl, 11, 0); /* File problem, other */
|
_mplas_err_resp (indCtrl, 11, 0); /* File problem, other */
|
||||||
//else
|
else
|
||||||
// mplas_fclose_resp (indCtrl);
|
mplas_fclose_resp (indCtrl);
|
||||||
}
|
}
|
||||||
#endif /* #if (MMS_FCLOSE_EN & RESP_EN) */
|
#endif /* #if (MMS_FCLOSE_EN & RESP_EN) */
|
||||||
|
|
||||||
@@ -1869,6 +1997,295 @@ MVL_REQ_PEND *reqCtrl;
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lnk20260508添加重启装置函数
|
||||||
|
int BuildResetDomName(ied_usr_t *ied_usr, char *domName, size_t domNameSize)
|
||||||
|
{
|
||||||
|
if (ied_usr == NULL || domName == NULL || domNameSize == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
domName[0] = '\0';
|
||||||
|
|
||||||
|
XmlConfigC cfg1;
|
||||||
|
memset(&cfg1, 0, sizeof(cfg1));
|
||||||
|
|
||||||
|
if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg1))
|
||||||
|
{
|
||||||
|
printf("========== XmlConfigC dump ==========\n");
|
||||||
|
printf("IEDControl = '%s'\n", cfg1.IEDControl);
|
||||||
|
printf("IEDname = '%s'\n", cfg1.IEDname);
|
||||||
|
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
|
||||||
|
printf("=====================================\n");
|
||||||
|
|
||||||
|
if (cfg1.IEDControl[0] != '\0')
|
||||||
|
{
|
||||||
|
snprintf(domName, domNameSize, "%s", cfg1.IEDControl);
|
||||||
|
printf("[RESET] use cfg1.IEDControl=%s\n", domName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ied_usr->LD_info && ied_usr->LD_info[0].LD_name)
|
||||||
|
{
|
||||||
|
snprintf(domName, domNameSize, "%s", ied_usr->LD_info[0].LD_name);
|
||||||
|
|
||||||
|
int len = strlen(domName);
|
||||||
|
if (len > 0 && isdigit(domName[len - 1]))
|
||||||
|
domName[len - 1] = '0';
|
||||||
|
|
||||||
|
printf("[RESET] use LD_name domName=%s\n", domName);
|
||||||
|
|
||||||
|
DIY_WARNLOG_CODE(ied_usr->terminal_id, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【WARN】未取到 IEDControl 信息,使用 LD_name=%s terminal_id=%s",
|
||||||
|
domName, ied_usr->terminal_id);
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(domName, domNameSize, "%s", "PQMonitorPQM0");
|
||||||
|
printf("[RESET] use default domName=%s\n", domName);
|
||||||
|
DIY_ERRORLOG_CODE(ied_usr->terminal_id, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【ERROR】未取到 LD 信息,使用默认 domName=%s terminal_id=%s",
|
||||||
|
domName, ied_usr->terminal_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ST_INT ledrs_var_type_create(MVL_NET_INFO* net_info,
|
||||||
|
OBJECT_NAME* varObj,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
MVL_REQ_PEND* reqCtrl;
|
||||||
|
GETVAR_REQ_INFO getvar_req;
|
||||||
|
VAR_ACC_TSPEC* type_spec;
|
||||||
|
ST_INT type_id = -1;
|
||||||
|
ST_RET ret;
|
||||||
|
|
||||||
|
memset(&getvar_req, 0, sizeof(getvar_req));
|
||||||
|
|
||||||
|
getvar_req.req_tag = GETVAR_NAME;
|
||||||
|
getvar_req.name = *varObj;
|
||||||
|
|
||||||
|
ret = mvla_getvar(net_info, &getvar_req, &reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
ret = waitReqDone(reqCtrl, timeOut);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
{
|
||||||
|
type_spec = &reqCtrl->u.getvar.resp_info->type_spec;
|
||||||
|
|
||||||
|
type_id = mvl_type_id_create(NULL,
|
||||||
|
type_spec->data,
|
||||||
|
type_spec->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqCtrl)
|
||||||
|
mvl_free_req_ctrl(reqCtrl);
|
||||||
|
|
||||||
|
return type_id;
|
||||||
|
}
|
||||||
|
static ST_INT create_oper_type_id(MVL_NET_INFO *net_info,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
const char *ctlName,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
OBJECT_NAME obj;
|
||||||
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
|
||||||
|
if (net_info == NULL || domName == NULL || ctlName == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&obj, 0, sizeof(obj));
|
||||||
|
|
||||||
|
apr_snprintf(varName,
|
||||||
|
sizeof(varName),
|
||||||
|
"LLN0$%s",
|
||||||
|
ctlName);
|
||||||
|
|
||||||
|
obj.object_tag = DOM_SPEC;
|
||||||
|
obj.domain_id = domName;
|
||||||
|
obj.obj_name.vmd_spec = varName;
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] create type dom=%s var=%s\n",
|
||||||
|
domName, varName);
|
||||||
|
|
||||||
|
return ledrs_var_type_create(net_info, &obj, timeOut);
|
||||||
|
}
|
||||||
|
void InitLedrsOperTypeForChannel(chnl_usr_t *chnl_usr)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] enter\n");
|
||||||
|
|
||||||
|
if (chnl_usr == NULL || chnl_usr->chnl == NULL ||
|
||||||
|
chnl_usr->chnl->ied == NULL || chnl_usr->net_info == NULL)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] invalid chnl_usr\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ied_t *ied = chnl_usr->chnl->ied;
|
||||||
|
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
||||||
|
|
||||||
|
if (ied_usr == NULL || ied_usr->LD_info == NULL)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] invalid ied_usr or LD_info\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] current inited=%d ledrs=%d reboot=%d reset=%d\n",
|
||||||
|
(int)ied_usr->oper_type_cache.inited,
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id,
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id,
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id);
|
||||||
|
|
||||||
|
if (ied_usr->oper_type_cache.inited == SD_TRUE)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] already inited\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char domName[256] = {0};
|
||||||
|
|
||||||
|
BuildResetDomName(ied_usr,
|
||||||
|
domName,
|
||||||
|
sizeof(domName));
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] final dom=%s\n", domName);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"CO$LEDRs$Oper",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] LEDRs type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"CO$Reboot$Oper",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] Reboot type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"ST$Mod$stVal",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] Reset type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id);
|
||||||
|
|
||||||
|
/* 无论成功失败,都不再重复初始化 */
|
||||||
|
ied_usr->oper_type_cache.inited = SD_TRUE;
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] finish inited=%d\n",
|
||||||
|
(int)ied_usr->oper_type_cache.inited);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ST_RET write_common_oper(chnl_usr_t *chnl_usr,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
const char *ctlName,
|
||||||
|
ST_INT oper_type_id,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
if (chnl_usr == NULL ||
|
||||||
|
chnl_usr->net_info == NULL ||
|
||||||
|
domName == NULL ||
|
||||||
|
ctlName == NULL ||
|
||||||
|
oper_type_id < 0)
|
||||||
|
{
|
||||||
|
printf("[OPER_WRITE] invalid param\n");
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
apr_snprintf(varName,
|
||||||
|
sizeof(varName),
|
||||||
|
"LLN0$%s",
|
||||||
|
ctlName);
|
||||||
|
|
||||||
|
Control_Oper_t oper;
|
||||||
|
memset(&oper, 0, sizeof(oper));
|
||||||
|
|
||||||
|
oper.ctlVal = SD_TRUE;
|
||||||
|
oper.origin.orCat = 3;
|
||||||
|
oper.origin.orIdent.len = 0;
|
||||||
|
oper.ctlNum = 1;
|
||||||
|
u_get_current_utc_time(&oper.T);
|
||||||
|
oper.Test = SD_FALSE;
|
||||||
|
oper.Check[0] = 0x00;
|
||||||
|
oper.Check[1] = 0x00;
|
||||||
|
|
||||||
|
if ((int)sizeof(Control_Oper_t) !=
|
||||||
|
mvl_type_ctrl[oper_type_id].data_size)
|
||||||
|
{
|
||||||
|
printf("[OPER_WRITE] SIZE MISMATCH ctl=%s local=%d runtime=%d\n",
|
||||||
|
ctlName,
|
||||||
|
(int)sizeof(Control_Oper_t),
|
||||||
|
mvl_type_ctrl[oper_type_id].data_size);
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[OPER_WRITE] dom=%s var=%s type_id=%d\n",
|
||||||
|
domName, varName, oper_type_id);
|
||||||
|
|
||||||
|
return mms_named_var_write(chnl_usr->net_info,
|
||||||
|
varName,
|
||||||
|
DOM_SPEC,
|
||||||
|
domName,
|
||||||
|
oper_type_id,
|
||||||
|
(ST_CHAR *)&oper,
|
||||||
|
timeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_RET mms_conclude_disconnect(MVL_NET_INFO *net_info, ST_INT timeOut)
|
||||||
|
{
|
||||||
|
MVL_REQ_PEND *reqCtrl = NULL;
|
||||||
|
ST_RET ret;
|
||||||
|
|
||||||
|
if (net_info == NULL)
|
||||||
|
return SD_FAILURE;
|
||||||
|
|
||||||
|
printf("[RESET] before mvl_concl\n");
|
||||||
|
|
||||||
|
ret = mvl_concl(net_info, &reqCtrl);
|
||||||
|
|
||||||
|
printf("[RESET] after mvl_concl ret=0x%X reqCtrl=%p\n",
|
||||||
|
ret, reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS && reqCtrl != NULL)
|
||||||
|
{
|
||||||
|
ret = waitReqDone(reqCtrl, timeOut);
|
||||||
|
|
||||||
|
printf("[RESET] conclude wait ret=0x%X\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqCtrl != NULL)
|
||||||
|
mvl_free_req_ctrl(reqCtrl);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_RET write_mod_stval(chnl_usr_t *chnl_usr,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
ST_INT16 value = 88;
|
||||||
|
|
||||||
|
apr_snprintf(varName, sizeof(varName), "LLN0$ST$Mod$stVal");
|
||||||
|
|
||||||
|
return mms_named_var_write(chnl_usr->net_info,
|
||||||
|
varName,
|
||||||
|
DOM_SPEC,
|
||||||
|
domName,
|
||||||
|
14, //int
|
||||||
|
(ST_CHAR *)&value,
|
||||||
|
timeOut);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* init_log_cfg */
|
/* init_log_cfg */
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ extern int SOCKET_PORT;
|
|||||||
extern int G_TEST_FLAG;
|
extern int G_TEST_FLAG;
|
||||||
extern int g_front_seg_index;
|
extern int g_front_seg_index;
|
||||||
extern int g_front_seg_num;
|
extern int g_front_seg_num;
|
||||||
|
extern int RECALL_ONLY_FLAG; //lnk20260309添加一个全局变量,标志是否只运行补招程序
|
||||||
|
|
||||||
#include "../rocketmq/SimpleProducer.h"
|
#include "../rocketmq/SimpleProducer.h"
|
||||||
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
||||||
@@ -187,48 +188,51 @@ apr_status_t init_rdb()
|
|||||||
init_config();
|
init_config();
|
||||||
GetServerIndexFromDB();
|
GetServerIndexFromDB();
|
||||||
|
|
||||||
rv = parse_device_cfg_web();
|
//只有补招运行时,统计不读取台账和模型
|
||||||
if (rv != APR_SUCCESS) {
|
if (RECALL_ONLY_FLAG != 1 || (g_node_id != STAT_DATA_BASE_NODE_ID)) {
|
||||||
echo_errg("Parsed device config xml file with error,try to run! \n");
|
rv = parse_device_cfg_web();
|
||||||
|
if (rv != APR_SUCCESS) {
|
||||||
|
echo_errg("Parsed device config xml file with error,try to run! \n");
|
||||||
|
|
||||||
//char buf[256];
|
//char buf[256];
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
//log_error("process", buf);
|
//log_error("process", buf);
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_LEDGER,"【ERROR】前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
//台账读取过后初始化各级的日志
|
//台账读取过后初始化各级的日志
|
||||||
init_loggers();
|
init_loggers();
|
||||||
|
|
||||||
rv = parse_model_cfg_web();
|
|
||||||
if (rv != APR_SUCCESS) {//不可能
|
|
||||||
echo_errg("Parsed model with error,try to run! \n");
|
|
||||||
|
|
||||||
//char buf[256];
|
rv = parse_model_cfg_web();
|
||||||
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
if (rv != APR_SUCCESS) {//不可能
|
||||||
//log_error("process", buf);
|
echo_errg("Parsed model with error,try to run! \n");
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
|
||||||
|
|
||||||
return rv;
|
//char buf[256];
|
||||||
}
|
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
//log_error("process", buf);
|
||||||
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
Set_xml_nodeinfo();//解析xml模型
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
rv = parse_rpt_log_ini();//报告块初始化
|
Set_xml_nodeinfo();//解析xml模型
|
||||||
if (rv != APR_SUCCESS) {
|
|
||||||
echo_errg("Failed to parse report log define ini file! \n");
|
|
||||||
|
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
rv = parse_rpt_log_ini();//报告块初始化
|
||||||
|
if (rv != APR_SUCCESS) {
|
||||||
|
echo_errg("Failed to parse report log define ini file! \n");
|
||||||
|
|
||||||
return rv;
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_RPTINIT,"【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app_get_private_config(g_my_conf_fname) != APR_SUCCESS) {
|
if (app_get_private_config(g_my_conf_fname) != APR_SUCCESS) {
|
||||||
echo_errg("Failed when processing private configuration\n");
|
echo_errg("Failed when processing private configuration\n");
|
||||||
|
|
||||||
DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程读取mms配置失败", get_front_msg_from_subdir(), g_front_seg_index);
|
DIY_ERRORLOG_CODE("process",0,LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程读取mms配置失败", get_front_msg_from_subdir(), g_front_seg_index);
|
||||||
|
|
||||||
return APR_EGENERAL;
|
return APR_EGENERAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,13 +144,19 @@ struct recall_t{
|
|||||||
int need_voltage;
|
int need_voltage;
|
||||||
};
|
};
|
||||||
typedef struct recall_xml_t recall_xml_t;
|
typedef struct recall_xml_t recall_xml_t;
|
||||||
struct recall_xml_t{
|
/*struct recall_xml_t{
|
||||||
int work_recall_num;
|
int work_recall_num;
|
||||||
int new_recall_num;
|
int new_recall_num;
|
||||||
recall_t work_recalls[MAX_RECALL_NUM];
|
recall_t work_recalls[MAX_RECALL_NUM];
|
||||||
recall_t new_recalls[MAX_RECALL_NUM];
|
recall_t new_recalls[MAX_RECALL_NUM];
|
||||||
|
};*/
|
||||||
|
/* 动态数组 + 容量字段 lnk20250801*/
|
||||||
|
struct recall_xml_t{
|
||||||
|
int work_cnt, work_cap;
|
||||||
|
int new_cnt , new_cap;
|
||||||
|
recall_t *work_recalls;
|
||||||
|
recall_t *new_recalls;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
struct element_usr_t{
|
struct element_usr_t{
|
||||||
char* FCD_ref;
|
char* FCD_ref;
|
||||||
@@ -249,6 +255,9 @@ struct LD_info_t{
|
|||||||
rptinfo_t **rptinfo; /**< rptinfo_t* 数组 */
|
rptinfo_t **rptinfo; /**< rptinfo_t* 数组 */
|
||||||
int read_flag ; //CZY 2023-02-28 判断是否将监测点是否有效
|
int read_flag ; //CZY 2023-02-28 判断是否将监测点是否有效
|
||||||
|
|
||||||
|
//测点日志等级
|
||||||
|
int log_level; //0 ERROR 1 WARN 2 NORMAL 3 DEBUG
|
||||||
|
|
||||||
char mp_id[256];//CZY 2023-08-20 监测点编码,例:8afaa
|
char mp_id[256];//CZY 2023-08-20 监测点编码,例:8afaa
|
||||||
char terminal_code[256];//CZY 2023-08-20 终端编码
|
char terminal_code[256];//CZY 2023-08-20 终端编码
|
||||||
//int ld_ins;//CZY 2023-08-20 逻辑设备实例号,例:1
|
//int ld_ins;//CZY 2023-08-20 逻辑设备实例号,例:1
|
||||||
@@ -263,8 +272,12 @@ struct LD_info_t{
|
|||||||
int rptPstRecvFlag;//CZY 2023-08-17 WW 2022-11-14判断报告是否收齐,rptRecvFlag=有效报告序号相加
|
int rptPstRecvFlag;//CZY 2023-08-17 WW 2022-11-14判断报告是否收齐,rptRecvFlag=有效报告序号相加
|
||||||
int rptPstRecvCheckFlag;//CZY 2023-08-17 WW 2022-11-14判断报告是否收齐,每次收到报告相加与rptRecvFlag一起判断是否收完
|
int rptPstRecvCheckFlag;//CZY 2023-08-17 WW 2022-11-14判断报告是否收齐,每次收到报告相加与rptRecvFlag一起判断是否收完
|
||||||
//报告
|
//报告
|
||||||
//不使用
|
|
||||||
|
int registcount;//lnk20250812
|
||||||
|
bool has_logged_regist;//lnk20250812
|
||||||
|
|
||||||
int iUnitOfTime;//CZY 2023-08-17 WW 2022年12月7日15:43:34 装置上送事件持续时间单位切换(0-ms; 1-s)
|
int iUnitOfTime;//CZY 2023-08-17 WW 2022年12月7日15:43:34 装置上送事件持续时间单位切换(0-ms; 1-s)
|
||||||
|
//不使用
|
||||||
int iStatOfTime;//CZY 2023-08-17 WW 2022年12月7日15:48:33 统计数据时间 0-北京时间 1-UTC时间
|
int iStatOfTime;//CZY 2023-08-17 WW 2022年12月7日15:48:33 统计数据时间 0-北京时间 1-UTC时间
|
||||||
int iJournalTime;//CZY 2023-08-17 WW 2022年12月7日15:52:32 补招日志时间(0-UTC时间(日志、录波文件均为UTC时间); 1-北京时间(日志北京时间、录波文件UTC时间 注:仅四川地区+8小时读取补招日志))
|
int iJournalTime;//CZY 2023-08-17 WW 2022年12月7日15:52:32 补招日志时间(0-UTC时间(日志、录波文件均为UTC时间); 1-北京时间(日志北京时间、录波文件UTC时间 注:仅四川地区+8小时读取补招日志))
|
||||||
//不使用
|
//不使用
|
||||||
@@ -307,6 +320,17 @@ struct LD_info_t{
|
|||||||
//录波
|
//录波
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//装置控制初始化
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ST_BOOLEAN inited;
|
||||||
|
|
||||||
|
ST_INT ledrs_oper_type_id;
|
||||||
|
ST_INT reboot_oper_type_id;
|
||||||
|
ST_INT reset_oper_type_id;
|
||||||
|
|
||||||
|
} MMS_OPER_TYPE_CACHE;
|
||||||
|
|
||||||
struct ied_usr_t{
|
struct ied_usr_t{
|
||||||
LD_info_t *LD_info; /**< LD数组 */
|
LD_info_t *LD_info; /**< LD数组 */
|
||||||
int dev_idx; /**< 设备序号 */
|
int dev_idx; /**< 设备序号 */
|
||||||
@@ -317,6 +341,8 @@ struct ied_usr_t{
|
|||||||
void *cookie;
|
void *cookie;
|
||||||
double last_call_wavelist_time ; //上次召录波列表时间
|
double last_call_wavelist_time ; //上次召录波列表时间
|
||||||
|
|
||||||
|
int log_level; //0 ERROR 1 WARN 2 NORMAL 3 DEBUG
|
||||||
|
|
||||||
char terminal_id[256];//CZY 2023-08-20 终端id,例:8afaa9a15707483a0157262f8e78077d
|
char terminal_id[256];//CZY 2023-08-20 终端id,例:8afaa9a15707483a0157262f8e78077d
|
||||||
char org_name[256];//CZY 2023-08-20 所属单位,例:南京供公司
|
char org_name[256];//CZY 2023-08-20 所属单位,例:南京供公司
|
||||||
char maint_name[256];//CZY 2023-08-20 运维单位,例:南京供公司
|
char maint_name[256];//CZY 2023-08-20 运维单位,例:南京供公司
|
||||||
@@ -331,6 +357,8 @@ struct ied_usr_t{
|
|||||||
|
|
||||||
bool lastconnectstat;//lnk20250704
|
bool lastconnectstat;//lnk20250704
|
||||||
bool has_logged_disconnect;//lnk20250704
|
bool has_logged_disconnect;//lnk20250704
|
||||||
|
|
||||||
|
MMS_OPER_TYPE_CACHE oper_type_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -494,6 +522,9 @@ int delete_recall_xml(char* id);
|
|||||||
int parse_recall_xml(recall_xml_t* recall_xml,char *id);
|
int parse_recall_xml(recall_xml_t* recall_xml,char *id);
|
||||||
void process_recall_config(recall_xml_t* recall_xml);
|
void process_recall_config(recall_xml_t* recall_xml);
|
||||||
|
|
||||||
|
void recall_xml_free(recall_xml_t *rx);//lnk20250801
|
||||||
|
void recall_xml_init(recall_xml_t *rx);
|
||||||
|
|
||||||
int init_rptctrl_by_count(LD_info_t* LD_info,int rptcount);
|
int init_rptctrl_by_count(LD_info_t* LD_info,int rptcount);
|
||||||
int fill_rptctrl_by_cfg(LD_info_t* LD_info,int rptno,char *buf);
|
int fill_rptctrl_by_cfg(LD_info_t* LD_info,int rptno,char *buf);
|
||||||
int init_logctrl_by_count(LD_info_t* LD_info,int logcount);
|
int init_logctrl_by_count(LD_info_t* LD_info,int logcount);
|
||||||
@@ -514,6 +545,37 @@ int extract_timestamp_from_cfg_file(char *comtrade_fn,long long *start_tm,long l
|
|||||||
int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int filenum, int* cfg_idx, int* dat_idx, char* file_base_name, char* file_yyyymm);
|
int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int filenum, int* cfg_idx, int* dat_idx, char* file_base_name, char* file_yyyymm);
|
||||||
QVVR_t* find_qvvr_by_trig_tm(LD_info_t* LD_info,long long trig_tm);
|
QVVR_t* find_qvvr_by_trig_tm(LD_info_t* LD_info,long long trig_tm);
|
||||||
|
|
||||||
|
void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr);
|
||||||
|
void InitLedrsOperTypeForChannel(chnl_usr_t *chnl_usr);
|
||||||
|
|
||||||
|
//lnk20250508添加重启装置函数
|
||||||
|
//根据抓包显示oper的data结构有6个item
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ST_BOOLEAN ctlVal;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ST_INT16 orCat;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ST_INT16 len;
|
||||||
|
ST_UINT8 data[64];
|
||||||
|
} orIdent;
|
||||||
|
|
||||||
|
} origin;
|
||||||
|
|
||||||
|
ST_UINT32 ctlNum;
|
||||||
|
|
||||||
|
MMS_UTC_TIME T;
|
||||||
|
|
||||||
|
ST_BOOLEAN Test;
|
||||||
|
|
||||||
|
ST_UCHAR Check[2];
|
||||||
|
|
||||||
|
} Control_Oper_t;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -488,7 +488,7 @@ void processQVVR_start(LD_info_t* LD_info)
|
|||||||
|
|
||||||
LD_info->qvvr[LD_info->qvvr_idx].used_status = QVVR_DATA_RECEIVED;//这个点标记为收到暂态数据
|
LD_info->qvvr[LD_info->qvvr_idx].used_status = QVVR_DATA_RECEIVED;//这个点标记为收到暂态数据
|
||||||
LD_info->qvvr[LD_info->qvvr_idx].QVVR_type = 0; //类型未定
|
LD_info->qvvr[LD_info->qvvr_idx].QVVR_type = 0; //类型未定
|
||||||
LD_info->qvvr[LD_info->qvvr_idx].timestamp = apr_time_sec(apr_time_now());//记录当前时间为暂态时间
|
LD_info->qvvr[LD_info->qvvr_idx].timestamp = apr_time_sec(apr_time_now());//记录当前时间
|
||||||
printf("\n~~~~~~~~~~~~~~~~~ processQVVR_start: line_id=%d \n",LD_info->line_id);
|
printf("\n~~~~~~~~~~~~~~~~~ processQVVR_start: line_id=%d \n",LD_info->line_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,13 +534,6 @@ void processQVVR_end(LD_info_t* LD_info)
|
|||||||
ied_t *ied = LD_info->ied;
|
ied_t *ied = LD_info->ied;
|
||||||
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
char full_key_m_c[256]; // 分配足够空间
|
|
||||||
char full_key_m_d[256]; // 分配足够空间
|
|
||||||
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", LD_info->mp_id);
|
|
||||||
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", LD_info->mp_id);
|
|
||||||
//监测点日志的key,lnk20250526
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
int find_paired = FALSE;
|
int find_paired = FALSE;
|
||||||
@@ -562,11 +555,11 @@ void processQVVR_end(LD_info_t* LD_info)
|
|||||||
long long utc_or_beijing;
|
long long utc_or_beijing;
|
||||||
if(strcmp(cfg.UnitOfTimeUnit, "1") == 0){//持续时间上送的是秒1还是毫秒0
|
if(strcmp(cfg.UnitOfTimeUnit, "1") == 0){//持续时间上送的是秒1还是毫秒0
|
||||||
s_or_ms = 0.001;
|
s_or_ms = 0.001;
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
//DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
s_or_ms = 1.0;
|
s_or_ms = 1.0;
|
||||||
DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是毫秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
//DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是毫秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strcmp(cfg.ValueOfTimeUnit, "utc") == 0){//上送的是utc还是北京
|
if(strcmp(cfg.ValueOfTimeUnit, "utc") == 0){//上送的是utc还是北京
|
||||||
@@ -578,11 +571,8 @@ void processQVVR_end(LD_info_t* LD_info)
|
|||||||
|
|
||||||
|
|
||||||
for (i=0;i<QVVR_NUM;i++) { //暂降/暂升/中断等进入处理,遍历所有波动位置
|
for (i=0;i<QVVR_NUM;i++) { //暂降/暂升/中断等进入处理,遍历所有波动位置
|
||||||
if (i==LD_info->qvvr_idx) //跳过监测点当前波动位置,第一次记录波形后,第一次的第三个事件会让0号点为QVVR_DATA_RECEIVED,
|
if (i==LD_info->qvvr_idx) //跳过监测点当前波动位置,不会和自己做匹配。第一次记录波形后,第一次的第一个事件会让0号点为QVVR_DATA_RECEIVED,
|
||||||
//第二次记录波形,第二次的第一个事件qvvr_idx=1,1号中为QVVR_DATA_RECEIVED,QVVR_start=1,跳过记录,
|
//第二次qvvr_idx=1,1号中为QVVR_DATA_RECEIVED,QVVR_start=0,会和0点做匹配
|
||||||
//第二次的第二个事件qvvr_idx=1,QVVR_start=0,记录到0中,0为QVVR_DATA_PAIRED
|
|
||||||
//第二次的第三个事件qvvr_idx=2,2号中为QVVR_DATA_RECEIVED,QVVR_start=1,跳过记录
|
|
||||||
//第二次录波匹配文件时应该匹配到1号的qvvrtime,但是1没有QVVR_DATA_PAIRED所以对不上,需要修改逻辑
|
|
||||||
{
|
{
|
||||||
printf("skip this index\n");
|
printf("skip this index\n");
|
||||||
continue;
|
continue;
|
||||||
@@ -638,7 +628,11 @@ void processQVVR_end(LD_info_t* LD_info)
|
|||||||
|
|
||||||
//匹配后再发qvvr,起始时间要填暂态触发的时间,就是第一次事件上送时只有时间没有值的那个时间
|
//匹配后再发qvvr,起始时间要填暂态触发的时间,就是第一次事件上送时只有时间没有值的那个时间
|
||||||
//mq日志
|
//mq日志
|
||||||
DIY_WARNLOG(full_key_m_d,"【WARN】监测点%s - id:%s 发生暂态事件",LD_info->name,LD_info->mp_id);
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_TRANSIENT,"【WARN】监测点%s - id:%s 发生暂态事件,暂态时间:%lld,暂态持续时间:%f,暂态幅值:%f,暂态类型:%d",LD_info->name,LD_info->mp_id,
|
||||||
|
LD_info->qvvr[LD_info->qvvr_idx].QVVR_time,
|
||||||
|
LD_info->qvvr[LD_info->qvvr_idx].QVVR_PerTime,
|
||||||
|
LD_info->qvvr[LD_info->qvvr_idx].QVVR_Amg,
|
||||||
|
LD_info->qvvr[LD_info->qvvr_idx].QVVR_type);
|
||||||
|
|
||||||
ret = transfer_json_qvvr_data(g_node_id, //这个参数没有使用
|
ret = transfer_json_qvvr_data(g_node_id, //这个参数没有使用
|
||||||
LD_info->line_id, //监测点序号
|
LD_info->line_id, //监测点序号
|
||||||
@@ -665,6 +659,15 @@ void processQVVR_end(LD_info_t* LD_info)
|
|||||||
LD_info->qvvr[LD_info->qvvr_idx].used_status = QVVR_DATA_NOT_USED; //全都没有匹配上直接释放这个点,下次事件可以直接在这个点上使用
|
LD_info->qvvr[LD_info->qvvr_idx].used_status = QVVR_DATA_NOT_USED; //全都没有匹配上直接释放这个点,下次事件可以直接在这个点上使用
|
||||||
printf("\nERROR:~~~~~~~~~~~~~ processQVVR qvvr returned to 0,but found no data to pair!, line_id=%d,QVVR_type=%d \n",
|
printf("\nERROR:~~~~~~~~~~~~~ processQVVR qvvr returned to 0,but found no data to pair!, line_id=%d,QVVR_type=%d \n",
|
||||||
LD_info->line_id, LD_info->qvvr[LD_info->qvvr_idx].QVVR_type);
|
LD_info->line_id, LD_info->qvvr[LD_info->qvvr_idx].QVVR_type);
|
||||||
|
|
||||||
|
//mq日志
|
||||||
|
if(strcmp(cfg.UnitOfTimeUnit, "1") == 0){//持续时间上送的是秒1还是毫秒0
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s记录了一个暂态事件但是没有匹配到事件的发生时间,装置型号:%s 配置的暂态持续时间单位是秒",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s记录了一个暂态事件但是没有匹配到事件的发生时间,装置型号:%s 配置的暂态持续时间单位是毫秒",LD_info->name,LD_info->mp_id,ied_usr->dev_type);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n~~~~~~~~~~~~~~~~~ processQVVR_end: line_id=%d \n",LD_info->line_id);
|
printf("\n~~~~~~~~~~~~~~~~~ processQVVR_end: line_id=%d \n",LD_info->line_id);
|
||||||
|
|||||||
176
mykafka.ini
Normal file
176
mykafka.ini
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
[Kafka]
|
||||||
|
BrokerList=
|
||||||
|
EventTopic=
|
||||||
|
KafkaFlag=
|
||||||
|
KafkaListSize=
|
||||||
|
|
||||||
|
RTDataTopic=Real_Time_Data_Topic
|
||||||
|
HisTopic=LN_Topic
|
||||||
|
PSTTopic=LN_Topic
|
||||||
|
PLTTopic=LN_Topic
|
||||||
|
AlmTopic=AlmTopic
|
||||||
|
SngTopic=SngTopic
|
||||||
|
|
||||||
|
[Oracle]
|
||||||
|
OtlType=
|
||||||
|
OtlConnect=
|
||||||
|
OtlFlag=
|
||||||
|
OtlConnectLimit=
|
||||||
|
SqlListSize=
|
||||||
|
|
||||||
|
[Comtrade]
|
||||||
|
NEWESTFlag=
|
||||||
|
|
||||||
|
[SFTP]
|
||||||
|
SFtpFlag=
|
||||||
|
|
||||||
|
[SagSource]
|
||||||
|
UpdateFlag=
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
UnitOfTime=
|
||||||
|
|
||||||
|
[Recall]
|
||||||
|
JournalTime=
|
||||||
|
recall_lenth=
|
||||||
|
recall_start=
|
||||||
|
recall_dailytime=
|
||||||
|
select_day=
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
ScreenFlag=
|
||||||
|
WebHost=
|
||||||
|
WebPort=
|
||||||
|
ScreenUrl=
|
||||||
|
|
||||||
|
[AccountUpdate]
|
||||||
|
Interval=
|
||||||
|
LastUpdateTime=
|
||||||
|
|
||||||
|
[MultiNode]
|
||||||
|
Interval=
|
||||||
|
|
||||||
|
[CommunicationLog]
|
||||||
|
StatusRecordDuration=
|
||||||
|
AbnormalRecordDuration=
|
||||||
|
|
||||||
|
[Postgres]
|
||||||
|
Database=
|
||||||
|
Username=
|
||||||
|
Password=
|
||||||
|
Schema=
|
||||||
|
Dnsname=
|
||||||
|
TablePrefix=
|
||||||
|
|
||||||
|
[Web]
|
||||||
|
ClientId=
|
||||||
|
ClientSecret=
|
||||||
|
TokenUrl=
|
||||||
|
DeviceUrl=
|
||||||
|
GrantType=
|
||||||
|
|
||||||
|
[Flag]
|
||||||
|
FileFlag=4
|
||||||
|
FrontInst=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
FrontIP=192.168.1.167
|
||||||
|
SendFlag=3
|
||||||
|
RecallOnlyFlag=0
|
||||||
|
|
||||||
|
[Ledger]
|
||||||
|
TerminalStatus="[0]"
|
||||||
|
MonitorStatus="[1,2]"
|
||||||
|
IcdFlag=0
|
||||||
|
IedCount=300
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
SocketEnable=0
|
||||||
|
SocketPort=13000
|
||||||
|
|
||||||
|
[Http]
|
||||||
|
HttpEnable=0
|
||||||
|
HttpIp=0.0.0.0
|
||||||
|
HttpPort=12000
|
||||||
|
WebDevice=http://192.168.1.68:10202/nodeDevice/nodeDeviceList
|
||||||
|
WebIcd=http://192.168.1.68:10202/icd/icdPathList
|
||||||
|
WebIntegrity=http://192.168.1.68:10202/LineIntegrityData/saveOrUpdateData
|
||||||
|
WebComflag=http://192.168.1.68:10202/dev/updateDevComFlag
|
||||||
|
WebEvent=http://192.168.1.68:10203/event/addEventDetail
|
||||||
|
WebFileupload=http://192.168.1.68:10207/file/upload
|
||||||
|
WebFiledownload=http://192.168.1.68:10207/file/download
|
||||||
|
|
||||||
|
[Oss]
|
||||||
|
OssEndpoint=
|
||||||
|
AccessKeyID=
|
||||||
|
AccessKeySecret=
|
||||||
|
BucketName=
|
||||||
|
|
||||||
|
[FrontNode]
|
||||||
|
Node=
|
||||||
|
|
||||||
|
[MySql]
|
||||||
|
ConStr=
|
||||||
|
|
||||||
|
[InfluxDb]
|
||||||
|
SelectUrl=
|
||||||
|
WriteUrl=
|
||||||
|
|
||||||
|
[RocketMq]
|
||||||
|
producer=Group_producer
|
||||||
|
Ipport=192.168.1.68:9876
|
||||||
|
TESTTopic=TEST_Topic
|
||||||
|
TESTTag=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
TESTKey=Test_Keys
|
||||||
|
Queuenum=4
|
||||||
|
|
||||||
|
Testflag=1
|
||||||
|
Testnum=0
|
||||||
|
Testtype=0
|
||||||
|
TestPort=11000
|
||||||
|
TestList=
|
||||||
|
|
||||||
|
consumer=Group_consumer
|
||||||
|
ConsumerIpport=192.168.1.68:9876
|
||||||
|
ConsumerTopicRT=ask_real_data_topic
|
||||||
|
ConsumerTagRT=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeyRT=Test_Keys
|
||||||
|
ConsumerAccessKey=rmqroot
|
||||||
|
ConsumerSecretKey=001@#njcnmq
|
||||||
|
ConsumerChannel=
|
||||||
|
ConsumerTopicUD=control_Topic
|
||||||
|
ConsumerTagUD=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeyUD=Test_Keys
|
||||||
|
ConsumerTopicRC=recall_Topic
|
||||||
|
ConsumerTagRC=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeyRC=Test_Keys
|
||||||
|
ConsumerTopicSET=process_Topic
|
||||||
|
ConsumerTagSET=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeySET=Test_Keys
|
||||||
|
ConsumerTopicLOG=ask_log_Topic
|
||||||
|
ConsumerTagLOG=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeyLOG=Test_Keys
|
||||||
|
ConsumerTopicFILE=File_Topic
|
||||||
|
ConsumerTagFILE=884d132ac3a01225fcacc8c10da07d09
|
||||||
|
ConsumerKeyFILE=Test_Keys
|
||||||
|
|
||||||
|
ConsumerTopicTEST=File_Topic
|
||||||
|
|
||||||
|
LOGTopic=log_Topic
|
||||||
|
LOGTag=Test_Tag
|
||||||
|
LOGKey=Test_Keys
|
||||||
|
CONNECTTopic=Device_Run_Flag_Topic
|
||||||
|
CONNECTTag=Test_Tag
|
||||||
|
CONNECTKey=Test_Keys
|
||||||
|
Heart_Beat_Topic=Heart_Beat_Topic
|
||||||
|
Heart_Beat_Tag=Test_Tag
|
||||||
|
Heart_Beat_Key=Test_Key
|
||||||
|
Topic_Reply_Topic=Topic_Reply_Topic
|
||||||
|
Topic_Reply_Tag=Test_Tag
|
||||||
|
Topic_Reply_Key=Test_Key
|
||||||
|
|
||||||
|
[LogRate]
|
||||||
|
ResetSec=3600
|
||||||
|
LimitSec=60
|
||||||
|
KeepAllMs=60000
|
||||||
|
KeepBurstMs=1000
|
||||||
|
KeepBurstCount=60
|
||||||
|
KeepHighFreqCount=10
|
||||||
@@ -1,21 +1,34 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include "../json/mms_json_inter.h"
|
#include "../json/mms_json_inter.h"
|
||||||
#include "../rocketmq/CProducer.h"
|
//#include "../rocketmq/CProducer.h"
|
||||||
#include "../rocketmq/CMessage.h"
|
//#include "../rocketmq/CMessage.h"
|
||||||
#include "../rocketmq/CSendResult.h"
|
//#include "../rocketmq/CSendResult.h"
|
||||||
|
//#include "../rocketmq/CPushConsumer.h"
|
||||||
#include "../rocketmq/CPushConsumer.h"
|
#include "../rocketmq/DefaultMQProducer.h"
|
||||||
|
#include "../rocketmq/MQMessage.h"
|
||||||
|
#include "../rocketmq/SendResult.h"
|
||||||
|
#include "../rocketmq/SessionCredentials.h"
|
||||||
|
#include "../rocketmq/MQMessageExt.h"
|
||||||
|
#include "../rocketmq/ConsumeType.h"
|
||||||
|
#include "../rocketmq/MQMessageListener.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace rocketmq;
|
||||||
|
|
||||||
/*添加测试函数lnk10-10*/
|
/*添加测试函数lnk10-10*/
|
||||||
void producer_send0();
|
//void producer_send0();
|
||||||
void StartSendMessage(CProducer* producer,const char* strbody);
|
//void StartSendMessage(CProducer* producer,const char* strbody);
|
||||||
void producer_send(const char* strbody);
|
//void producer_send(const char* strbody);
|
||||||
void rocketmq_producer_send(const char* strbody,const char* topic);
|
//void rocketmq_producer_send(const char* strbody,const char* topic);
|
||||||
void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic);
|
//void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic);
|
||||||
|
void rocketmq_producer_send(const std::string& body,
|
||||||
|
const std::string& topic,
|
||||||
|
const std::string& tags,
|
||||||
|
const std::string& keys);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void rocketmq_test_rt();
|
void rocketmq_test_rt();
|
||||||
void rocketmq_test_ud();
|
void rocketmq_test_ud();
|
||||||
@@ -32,17 +45,25 @@ extern void my_rocketmq_send(Ckafka_data_t& data);
|
|||||||
void InitializeProducer();
|
void InitializeProducer();
|
||||||
void ShutdownAndDestroyProducer();
|
void ShutdownAndDestroyProducer();
|
||||||
//////////////////////////////////////////////////////消费者
|
//////////////////////////////////////////////////////消费者
|
||||||
void InitializeConsumer(const std::string& consumerName, const std::string& nameServer, const char* topic, const char* tag, const std::string& key);
|
typedef ConsumeStatus (*MessageCallBack)(
|
||||||
void ShutdownAndDestroyConsumer();
|
const MQMessageExt& msg
|
||||||
|
);
|
||||||
|
|
||||||
struct Subscription {
|
struct Subscription {
|
||||||
std::string topic;
|
std::string topic;
|
||||||
std::string tag;
|
std::string tag;
|
||||||
MessageCallBack callback;
|
MessageCallBack callback;
|
||||||
|
|
||||||
Subscription(const std::string& t, const std::string& tg, MessageCallBack cb)
|
Subscription(const std::string& t,
|
||||||
: topic(t), tag(tg), callback(cb) {std::cout << "Subscription topic: " << topic << std::endl;}
|
const std::string& tg,
|
||||||
|
MessageCallBack cb)
|
||||||
|
: topic(t), tag(tg), callback(cb) {}
|
||||||
};
|
};
|
||||||
|
//void InitializeConsumer(const std::string& consumerName, const std::string& nameServer, const char* topic, const char* tag, const std::string& key);
|
||||||
|
void InitializeConsumer(const std::string& consumerName,
|
||||||
|
const std::string& nameServer,
|
||||||
|
const std::vector<Subscription>& subscriptions);
|
||||||
|
void ShutdownAndDestroyConsumer();
|
||||||
|
|
||||||
void rocketmq_consumer_receive(
|
void rocketmq_consumer_receive(
|
||||||
const std::string& consumerName,
|
const std::string& consumerName,
|
||||||
|
|||||||
350
set_process.sh
350
set_process.sh
@@ -8,8 +8,215 @@
|
|||||||
|
|
||||||
#前置all的重置或者新增都是由稳态的第一个进程来处理,所有进程收到这条消息后先判断自己的进程号是否是1,而且是稳态,否则不处理,所有操作均由这个进程完成,
|
#前置all的重置或者新增都是由稳态的第一个进程来处理,所有进程收到这条消息后先判断自己的进程号是否是1,而且是稳态,否则不处理,所有操作均由这个进程完成,
|
||||||
|
|
||||||
|
if [ -z "$SETSID" ]; then
|
||||||
|
export SETSID=1
|
||||||
|
nohup setsid "$0" "$@" >> /tmp/set_process_detach.log 2>&1 < /dev/null &
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 关闭从父进程继承来的 socket / pipe / 文件描述符
|
||||||
|
for fd_path in /proc/$$/fd/*; do
|
||||||
|
fd_num=$(basename "$fd_path")
|
||||||
|
case "$fd_num" in
|
||||||
|
0|1|2) ;;
|
||||||
|
*) eval "exec ${fd_num}>&-" 2>/dev/null ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
# 设置日志文件路径
|
# 设置日志文件路径
|
||||||
LOGFILE="$FEP_ENV/dat/log/start_fe.log"
|
LOGFILE="/FeProject/dat/log/start_fe.log"
|
||||||
|
|
||||||
|
INI_FILE="/FeProject/etc/config/mykafka.ini"
|
||||||
|
|
||||||
|
LOCK_FILE="/tmp/set_process.lock"
|
||||||
|
|
||||||
|
if [ -f "$LOCK_FILE" ]; then
|
||||||
|
old_pid=$(cat "$LOCK_FILE")
|
||||||
|
if ps -p "$old_pid" > /dev/null 2>&1; then
|
||||||
|
echo "Already running: $old_pid"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Stale lock found, removing"
|
||||||
|
rm -f "$LOCK_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $$ > "$LOCK_FILE"
|
||||||
|
trap "rm -f $LOCK_FILE" EXIT
|
||||||
|
|
||||||
|
get_ini_value() {
|
||||||
|
local key="$1"
|
||||||
|
local line
|
||||||
|
|
||||||
|
line=$(grep -E "^[[:space:]]*${key}=" "$INI_FILE" | tail -n 1)
|
||||||
|
[ -z "$line" ] && return 1
|
||||||
|
|
||||||
|
# 去掉 key=
|
||||||
|
line="${line#*=}"
|
||||||
|
# 去掉首尾空格
|
||||||
|
line=$(echo "$line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
|
||||||
|
[ -n "$line" ] || return 1
|
||||||
|
echo "$line"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo "$@" | tee -a "$LOGFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_local_port_released() {
|
||||||
|
local PORT="$1"
|
||||||
|
|
||||||
|
for retry in $(seq 1 3); do
|
||||||
|
for i in $(seq 1 20); do
|
||||||
|
if ! ss -lntp 2>/dev/null | grep -q ":${PORT}[[:space:]]"; then
|
||||||
|
log "[OK] Local port $PORT released"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
log "[WAIT] Local port $PORT still in use... ($i/20)"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
log "[RETRY] Local port $PORT not released, retry $retry/3"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
log "[FAIL] Local port $PORT still in use after retries:"
|
||||||
|
ss -lntp 2>/dev/null | grep ":${PORT}[[:space:]]" | tee -a "$LOGFILE"
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
check_remote_conn_released() {
|
||||||
|
local REMOTE_IP="$1"
|
||||||
|
local REMOTE_PORT="$2"
|
||||||
|
|
||||||
|
for retry in $(seq 1 3); do
|
||||||
|
for i in $(seq 1 20); do
|
||||||
|
if ! ss -ntp 2>/dev/null \
|
||||||
|
| grep "${REMOTE_IP}:${REMOTE_PORT}" \
|
||||||
|
| grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' >/dev/null; then
|
||||||
|
log "[OK] Remote ${REMOTE_IP}:${REMOTE_PORT} released"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "[WAIT] Remote ${REMOTE_IP}:${REMOTE_PORT} still exists... ($i/20)"
|
||||||
|
ss -ntp 2>/dev/null \
|
||||||
|
| grep "${REMOTE_IP}:${REMOTE_PORT}" \
|
||||||
|
| grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' \
|
||||||
|
| tee -a "$LOGFILE"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
log "[RETRY] Remote ${REMOTE_IP}:${REMOTE_PORT} not released, retry $retry/3"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
log "[FAIL] Remote ${REMOTE_IP}:${REMOTE_PORT} still exists:"
|
||||||
|
ss -ntp 2>/dev/null \
|
||||||
|
| grep "${REMOTE_IP}:${REMOTE_PORT}" \
|
||||||
|
| grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' \
|
||||||
|
| tee -a "$LOGFILE"
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
check_value_released() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
|
||||||
|
[ -z "$value" ] && return 0
|
||||||
|
|
||||||
|
# 纯端口
|
||||||
|
if echo "$value" | grep -Eq '^[0-9]+$'; then
|
||||||
|
[ "$value" = "0" ] && { log "[SKIP] $key disabled"; return 0; }
|
||||||
|
|
||||||
|
log "[CHECK] $key local port: $value"
|
||||||
|
check_local_port_released "$value"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# URL
|
||||||
|
if echo "$value" | grep -Eq '^[a-zA-Z]+://'; then
|
||||||
|
local hostport ip port
|
||||||
|
hostport=$(echo "$value" | sed -n 's#^[a-zA-Z]\+://\([^/]*\).*#\1#p')
|
||||||
|
ip="${hostport%%:*}"
|
||||||
|
port="${hostport##*:}"
|
||||||
|
|
||||||
|
if [ -n "$ip" ] && [ -n "$port" ] && [ "$ip" != "$port" ]; then
|
||||||
|
log "[CHECK] $key remote: $ip:$port"
|
||||||
|
check_remote_conn_released "$ip" "$port"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "[SKIP] $key invalid URL: $value"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ip:port
|
||||||
|
if echo "$value" | grep -Eq '^[^:]+:[0-9]+$'; then
|
||||||
|
local ip="${value%%:*}"
|
||||||
|
local port="${value##*:}"
|
||||||
|
|
||||||
|
log "[CHECK] $key remote: $ip:$port"
|
||||||
|
check_remote_conn_released "$ip" "$port"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "[SKIP] $key unsupported value: $value"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_key_released() {
|
||||||
|
local key="$1"
|
||||||
|
local value
|
||||||
|
|
||||||
|
value=$(get_ini_value "$key") || {
|
||||||
|
log "[SKIP] $key not found"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log "==== Checking $key = $value ===="
|
||||||
|
check_value_released "$key" "$value"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
check_all_resources_released() {
|
||||||
|
local ret=0
|
||||||
|
|
||||||
|
log "=============================="
|
||||||
|
log " Start checking resources..."
|
||||||
|
log "=============================="
|
||||||
|
|
||||||
|
# 本地端口
|
||||||
|
check_key_released "TestPort" || ret=1
|
||||||
|
check_key_released "HttpPort" || ret=1
|
||||||
|
check_key_released "SocketPort" || ret=1
|
||||||
|
|
||||||
|
# MQ
|
||||||
|
check_key_released "Ipport" || ret=1
|
||||||
|
check_key_released "ConsumerIpport" || ret=1
|
||||||
|
|
||||||
|
# Web
|
||||||
|
check_key_released "WebDevice" || ret=1
|
||||||
|
check_key_released "WebIcd" || ret=1
|
||||||
|
check_key_released "WebIntegrity" || ret=1
|
||||||
|
check_key_released "WebComflag" || ret=1
|
||||||
|
check_key_released "WebEvent" || ret=1
|
||||||
|
check_key_released "WebFileupload" || ret=1
|
||||||
|
check_key_released "WebFiledownload" || ret=1
|
||||||
|
|
||||||
|
if [ $ret -eq 0 ]; then
|
||||||
|
log "✅ ALL resources released"
|
||||||
|
else
|
||||||
|
log "❌ Some resources NOT released"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 输出当前时间并打印进程停止信息
|
# 输出当前时间并打印进程停止信息
|
||||||
echo "" ; echo ""
|
echo "" ; echo ""
|
||||||
@@ -20,7 +227,7 @@ echo "****** `date "+%F %R:%S"` start setting Processes after 3 sec ******" >>"$
|
|||||||
|
|
||||||
# 函数检查并处理日志文件大小
|
# 函数检查并处理日志文件大小
|
||||||
check_log_file() {
|
check_log_file() {
|
||||||
if [ -n "$1" ]; then
|
if [ -n "$1" ] && [ -f "$1" ]; then
|
||||||
FILE_SIZE=0
|
FILE_SIZE=0
|
||||||
FILE_SIZE=$(du "$1" | awk '{print $1}')
|
FILE_SIZE=$(du "$1" | awk '{print $1}')
|
||||||
|
|
||||||
@@ -45,23 +252,46 @@ check_log_file $LOGFILE
|
|||||||
|
|
||||||
# 定义查找并杀死进程的函数
|
# 定义查找并杀死进程的函数
|
||||||
kill_process_by_name() {
|
kill_process_by_name() {
|
||||||
PROCESS_NAME=$1
|
local PROCESS_NAME="$1"
|
||||||
PID=$(ps -ef | grep "$PROCESS_NAME" | grep -v "grep" | awk '{print $2}')
|
local PIDS
|
||||||
|
|
||||||
if [ -n "$PID" ]; then
|
PIDS=$(ps -ef | grep "$PROCESS_NAME" | grep -v grep | awk '{print $2}')
|
||||||
echo "Found process '$PROCESS_NAME' with PID: $PID"
|
|
||||||
|
if [ -n "$PIDS" ]; then
|
||||||
|
echo "Found process '$PROCESS_NAME' with PID(s): $PIDS"
|
||||||
echo "Killing process..."
|
echo "Killing process..."
|
||||||
kill -9 $PID
|
|
||||||
if [ $? -eq 0 ]; then
|
for pid in $PIDS; do
|
||||||
echo "Process '$PROCESS_NAME' killed successfully."
|
kill -15 "$pid" 2>/dev/null
|
||||||
else
|
done
|
||||||
echo "Failed to kill the process '$PROCESS_NAME'."
|
|
||||||
fi
|
sleep 3
|
||||||
|
|
||||||
|
for pid in $PIDS; do
|
||||||
|
if ps -p "$pid" >/dev/null 2>&1; then
|
||||||
|
echo "Process still exists, force kill: $pid"
|
||||||
|
kill -9 "$pid" 2>/dev/null
|
||||||
|
fi
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo "Process '$PROCESS_NAME' not found."
|
echo "Process '$PROCESS_NAME' not found."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait_all_exit() {
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
COUNT=$(ps -ef | grep -E 'pt61850netd_pqfe|fe_watchdog' | grep -v grep | wc -l)
|
||||||
|
if [ "$COUNT" -eq 0 ]; then
|
||||||
|
echo "All FE processes exited"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "Waiting FE processes exit... ($COUNT still running)"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "Timeout waiting FE processes exit"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# 功能块开始
|
# 功能块开始
|
||||||
handle_reset() {
|
handle_reset() {
|
||||||
# 功能:reset
|
# 功能:reset
|
||||||
@@ -71,70 +301,79 @@ handle_reset() {
|
|||||||
if [ "$2" == "all" ]; then
|
if [ "$2" == "all" ]; then
|
||||||
|
|
||||||
# 关闭旧的看门狗进程
|
# 关闭旧的看门狗进程
|
||||||
kill_process_by_name "/FeProject/bin/fe_watchdog"
|
#kill_process_by_name "/FeProject/bin/fe_watchdog"
|
||||||
|
|
||||||
# 关闭旧的 stat 进程
|
# 关闭旧的 stat 进程
|
||||||
kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_stat_data"
|
#kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_stat_data"
|
||||||
|
|
||||||
# 关闭旧的 recall 进程
|
# 关闭旧的 recall 进程
|
||||||
kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_recallhis_data"
|
#kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_recallhis_data"
|
||||||
|
|
||||||
# 关闭旧的 3s 进程
|
# 关闭旧的 3s 进程
|
||||||
kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_3s_data"
|
#kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_3s_data"
|
||||||
|
|
||||||
# 关闭旧的 comtrade 进程
|
# 关闭旧的 comtrade 进程
|
||||||
kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_soe_comtrade"
|
#kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_soe_comtrade"
|
||||||
|
|
||||||
|
/FeProject/boot/stop_fe.sh
|
||||||
|
|
||||||
|
wait_all_exit || exit 1
|
||||||
|
|
||||||
|
check_all_resources_released || exit 1
|
||||||
|
|
||||||
#关闭进程后等待一段时间,防止端口占用
|
#关闭进程后等待一段时间,防止端口占用
|
||||||
#sleep 5
|
sleep 5
|
||||||
|
|
||||||
# 清空 runtime.cf 中的所有进程配置
|
# 清空 runtime.cf 中的所有进程配置
|
||||||
sed -i '/cfg_stat_data/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_stat_data/d' /FeProject/etc/runtime.cf
|
||||||
sed -i '/cfg_recallhis_data/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_recallhis_data/d' /FeProject/etc/runtime.cf
|
||||||
sed -i '/cfg_3s_data/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_3s_data/d' /FeProject/etc/runtime.cf
|
||||||
sed -i '/cfg_soe_comtrade/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_soe_comtrade/d' /FeProject/etc/runtime.cf
|
||||||
sed -i '/fe_watchdog/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/fe_watchdog/d' /FeProject/etc/runtime.cf
|
||||||
|
|
||||||
# 根据进程号添加对应进程配置
|
# 根据进程号添加对应进程配置
|
||||||
if [ "$1" -eq 1 ]; then
|
if [ "$1" -eq 1 ]; then
|
||||||
#看门狗固定放在第一个,防止stop时会把要杀死的进程重启
|
#看门狗固定放在第一个,防止stop时会把要杀死的进程重启
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /FeProject/etc/runtime.cf
|
||||||
# 进程号为 1,按固定格式添加
|
# 进程号为 1,按固定格式添加
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s 1_1^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
|
|
||||||
else
|
else
|
||||||
#看门狗固定放在第一个,防止stop时会把要杀死的进程重启
|
#看门狗固定放在第一个,防止stop时会把要杀死的进程重启
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /FeProject/etc/runtime.cf
|
||||||
# 进程号大于 1,按 -s ${i}_ 格式添加
|
# 进程号大于 1,按 -s ${i}_ 格式添加
|
||||||
for i in $(seq 1 $1); do
|
for i in $(seq 1 $1); do
|
||||||
# 在 runtime.cf 中插入对应的配置行,直接插入变量替换结果
|
# 在 runtime.cf 中插入对应的配置行,直接插入变量替换结果
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
done
|
done
|
||||||
#以下部分没有多进程
|
#以下部分没有多进程
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 修改后等一下
|
||||||
|
sleep 1
|
||||||
|
|
||||||
# 确保文件已被写入并刷新
|
# 确保文件已被写入并刷新
|
||||||
sync
|
sync
|
||||||
|
|
||||||
# 重新启动服务
|
# 重新启动服务
|
||||||
|
|
||||||
/home/pq/FeProject/boot/start_fe.sh
|
/FeProject/boot/start_fe.sh
|
||||||
|
|
||||||
echo "****** reset all in $1******" >>"$LOGFILE"
|
echo "****** reset all in $1******" >>"$LOGFILE"
|
||||||
elif [ "$2" == "stat" ]; then
|
elif [ "$2" == "stat" ]; then
|
||||||
# 清空 runtime.cf 中包含 cfg_stat_data 的行
|
# 清空 runtime.cf 中包含 cfg_stat_data 的行
|
||||||
sed -i '/cfg_stat_data/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_stat_data/d' /FeProject/etc/runtime.cf
|
||||||
|
|
||||||
# 根据进程号来添加新的进程配置
|
# 根据进程号来添加新的进程配置
|
||||||
for i in $(seq 1 $1); do
|
for i in $(seq 1 $1); do
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
done
|
done
|
||||||
|
|
||||||
# 关闭旧的看门狗进程
|
# 关闭旧的看门狗进程
|
||||||
@@ -146,16 +385,16 @@ handle_reset() {
|
|||||||
#sleep 5
|
#sleep 5
|
||||||
|
|
||||||
# 启动服务不影响其他功能的进程
|
# 启动服务不影响其他功能的进程
|
||||||
/home/pq/FeProject/boot/start_fe.sh
|
/FeProject/boot/start_fe.sh
|
||||||
|
|
||||||
echo "****** reset stat in $1******" >>"$LOGFILE"
|
echo "****** reset stat in $1******" >>"$LOGFILE"
|
||||||
elif [ "$2" == "recall" ]; then
|
elif [ "$2" == "recall" ]; then
|
||||||
# 清空 runtime.cf 中包含 cfg_recallhis_data 的行
|
# 清空 runtime.cf 中包含 cfg_recallhis_data 的行
|
||||||
sed -i '/cfg_recallhis_data/d' /home/pq/FeProject/etc/runtime.cf
|
sed -i '/cfg_recallhis_data/d' /FeProject/etc/runtime.cf
|
||||||
|
|
||||||
# 根据进程号来添加新的进程配置
|
# 根据进程号来添加新的进程配置
|
||||||
for i in $(seq 1 $1); do
|
for i in $(seq 1 $1); do
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
done
|
done
|
||||||
|
|
||||||
# 关闭旧的看门狗进程
|
# 关闭旧的看门狗进程
|
||||||
@@ -166,7 +405,7 @@ handle_reset() {
|
|||||||
#sleep 5
|
#sleep 5
|
||||||
|
|
||||||
# 启动服务不影响其他功能的进程
|
# 启动服务不影响其他功能的进程
|
||||||
/home/pq/FeProject/boot/start_fe.sh
|
/FeProject/boot/start_fe.sh
|
||||||
|
|
||||||
echo "****** reset recall in $1******" >>"$LOGFILE"
|
echo "****** reset recall in $1******" >>"$LOGFILE"
|
||||||
else
|
else
|
||||||
@@ -190,22 +429,22 @@ handle_add() {
|
|||||||
# 如果 $1 在 1 和 10 之间,进入处理逻辑
|
# 如果 $1 在 1 和 10 之间,进入处理逻辑
|
||||||
if [ "$2" == "all" ]; then
|
if [ "$2" == "all" ]; then
|
||||||
# 检查是否已存在该条目,避免重复添加
|
# 检查是否已存在该条目,避免重复添加
|
||||||
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /home/pq/FeProject/etc/runtime.cf; then
|
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /home/pq/FeProject/etc/runtime.cf; then
|
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
fi
|
fi
|
||||||
elif [ "$2" == "stat" ]; then
|
elif [ "$2" == "stat" ]; then
|
||||||
# 检查是否已存在该条目,避免重复添加
|
# 检查是否已存在该条目,避免重复添加
|
||||||
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /home/pq/FeProject/etc/runtime.cf; then
|
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
fi
|
fi
|
||||||
elif [ "$2" == "recall" ]; then
|
elif [ "$2" == "recall" ]; then
|
||||||
# 检查是否已存在该条目,避免重复添加
|
# 检查是否已存在该条目,避免重复添加
|
||||||
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /home/pq/FeProject/etc/runtime.cf; then
|
if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then
|
||||||
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /home/pq/FeProject/etc/runtime.cf
|
sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "****** process add type null ******"
|
echo "****** process add type null ******"
|
||||||
@@ -218,7 +457,7 @@ handle_add() {
|
|||||||
#sleep 5
|
#sleep 5
|
||||||
|
|
||||||
# 启动服务,不影响正在运行的进程
|
# 启动服务,不影响正在运行的进程
|
||||||
/home/pq/FeProject/boot/start_fe.sh
|
/FeProject/boot/start_fe.sh
|
||||||
|
|
||||||
else
|
else
|
||||||
# 如果 $1 不在 1 到 10 之间,记录错误日志
|
# 如果 $1 不在 1 到 10 之间,记录错误日志
|
||||||
@@ -230,14 +469,13 @@ handle_add() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 获取当前脚本的进程ID
|
# 获取当前脚本的进程ID
|
||||||
CURRENT_PID=$$
|
#CURRENT_PID=$$
|
||||||
|
|
||||||
# 检查是否有其他的set_process.sh脚本正在运行,排除当前脚本
|
# 检查是否有其他的set_process.sh脚本正在运行,排除当前脚本
|
||||||
if pgrep -f "set_process.sh" | grep -v "^$CURRENT_PID$" > /dev/null; then
|
#if pgrep -f "set_process.sh" | grep -v "^$CURRENT_PID$" > /dev/null; then
|
||||||
echo "set_process.sh is already running. Exiting..."
|
# echo "set_process.sh is already running. Exiting..."
|
||||||
echo "set_process.sh is already running. Exiting..." >>"$LOGFILE"
|
# echo "set_process.sh is already running. Exiting..." >>"$LOGFILE"
|
||||||
exit 1
|
# exit 1
|
||||||
fi
|
#fi
|
||||||
|
|
||||||
#脚本应该等待3秒钟
|
#脚本应该等待3秒钟
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|||||||
Reference in New Issue
Block a user