华泰实现的IEC104

仅支持接收数据
main
Matthew 2 years ago
parent 3a349d35bc
commit 7b5c7a8c3c

@ -0,0 +1,8 @@
/********************************************************************/
# ht_iec104.conf
# date : 2018.09.01
# auther : huatek by liuyx
# Copyright (C) 2018, huatek, Inc.
/********************************************************************/
[IEC_DEVCOUNT]
# 涓诲彉璁惧鎬绘暟閲

@ -0,0 +1,8 @@
/********************************************************************/
# ht_iec104.conf
# date : 2018.09.01
# auther : huatek by liuyx
# Copyright (C) 2018, huatek, Inc.
/********************************************************************/
[IEC_DEVCOUNT]
# 涓诲彉璁惧鎬绘暟閲

@ -0,0 +1,52 @@
/********************************************************************/
# ht_service.conf
# date : 2018.09.01
# auther : huatek by liuyx
# Copyright (C) 2018, huatek, Inc.
/********************************************************************/
[HT_MONITOR]
# server monitor flag, true: monitor, false:no monitor
monitor_enable = true
[HT_VERSION]
# server version info, max length=32(byte)
ht_server_version = 2019.06.11
[HT_LOCAL_HOST]
local_host_addr = 127.0.0.1
local_tcp_port = 2404
[HT_REMOTE_HOST]
#remote_host_addr = 192.168.1.1
remote_host_addr = 127.0.0.1
remote_host_port = 2404
[HT_SOCKET]
max_epoll_limit = 2000
timeout_t0 = 30
timeout_t1 = 15
timeout_t2 = 10
timeout_t3 = 20
iec_k = 8
iec_w = 3
# application database config parameter
[HT_DATABASE]
db_host_addr = 192.168.128.86
db_host_port = 3306
db_name = hmf_0617
db_username = root
db_password = 123456
db_min_conn = 5
db_max_conn = 8
[HT_THREAD_NUMBER]
thread_recv_num = 2
thread_parse_num = 5
thread_opration_num = 3
thread_respone_num = 2
[HT_LOGGER]
logger = console,debug,error,warning,package
#logger = error,warning

@ -0,0 +1,15 @@
/********************************************************************/
# htimg.conf
# date : 2018.09.01
# auther : huatek by liuyx
# Copyright (C) 2006-2018, huatek, Inc.
# -------------------------------------------------------------------
# 浠〃鍗曚綅绫诲瀷鍙婂崟浣嶅畾涔夊搴斿叧绯昏〃
# ----------------------------------------
# 绫诲瀷 | 鍗曚綅瀹氫箟 |
# -------------+-------------------------+
# meter_type | meter_units |
# -------------+-------------------+-----+
# | 0 | 1 | 2 | 3 |
# = 0 +-------------------+-----+
# (鐢垫祦) | 寰畨 | 姣畨 | 瀹

@ -0,0 +1,15 @@
/********************************************************************/
# htimg.conf
# date : 2018.09.01
# auther : huatek by liuyx
# Copyright (C) 2006-2018, huatek, Inc.
# -------------------------------------------------------------------
# 浠〃鍗曚綅绫诲瀷鍙婂崟浣嶅畾涔夊搴斿叧绯昏〃
# ----------------------------------------
# 绫诲瀷 | 鍗曚綅瀹氫箟 |
# -------------+-------------------------+
# meter_type | meter_units |
# -------------+-------------------+-----+
# | 0 | 1 | 2 | 3 |
# = 0 +-------------------+-----+
# (鐢垫祦) | 寰畨 | 姣畨 | 瀹

@ -0,0 +1,14 @@
rtsp://192.168.1.12/stream65.sdp
rtsp://192.168.1.12/stream66.sdp
rtsp://192.168.1.12/stream67.sdp
rtsp://192.168.1.12/stream68.sdp
rtsp://192.168.1.12/stream69.sdp
rtsp://192.168.1.12/stream70.sdp
rtsp://192.168.1.12/stream71.sdp
rtsp://192.168.1.12/stream72.sdp
rtsp://192.168.1.12/stream73.sdp
rtsp://192.168.1.12/stream74.sdp
rtsp://192.168.1.12/stream75.sdp
rtsp://192.168.1.12/stream76.sdp
rtsp://192.168.1.12/stream80.sdp
rtsp://192.168.1.12/stream81.sdp

@ -0,0 +1,84 @@
/****************************************************************************
** File name : HTCP56Time.h
** Description : define data type
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_CP56TIME_H
#define __HT_CP56TIME_H
//
// CP56Time IEC 60870-5-104 time data type implementation
//
#pragma pack (push ,1)
#include <time.h>
#ifndef _WIN32
typedef struct _SYSTEMTIME {
unsigned short wYear;
unsigned short wMonth;
unsigned short wDayOfWeek;
unsigned short wDay;
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
unsigned short wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
typedef struct _FILETIME {
unsigned long dwLowDateTime;
unsigned long dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
#endif
typedef struct cp56time {
u_short msec;
u_char min :6;
u_char res1 :1;
u_char iv :1;
u_char hour :5;
u_char res2 :2;
u_char su :1;
u_char mday :5;
u_char wday :3;
u_char month :4;
u_char res3 :4;
u_char year :7;
u_char res4 :1;
} cp56time ;
class CP56Time
{
private:
SYSTEMTIME stime;
bool valid;
bool genuine;
bool summer;
public:
CP56Time(unsigned char *data);
~CP56Time(void);
void GetTimeString(char *buf, size_t size);
FILETIME _GetFileTime(void);
SYSTEMTIME _GetSystemTime(void);
void ActualTimeToCP56Time(unsigned char *data);
void TimeToCP56Time(FILETIME *ft, unsigned char *data);
void TimeToCP56Time(SYSTEMTIME *st, unsigned char *data);
void CP56TimeToTime(unsigned char *data, FILETIME *ft);
void CP56TimeToTime(unsigned char *data, SYSTEMTIME *st);
};
#pragma pack (pop)
#endif // end __HT_CP56TIME_H

@ -0,0 +1,84 @@
/****************************************************************************
** File name : HTCP56Time2a.h
** Description : define data type
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_CP56TIME2A_H
#define __HT_CP56TIME2A_H
//
// CP56Time2a IEC 60870-5-104 time data type implementation
//
#pragma pack (push ,1)
#include <time.h>
#ifndef _WIN32
typedef struct _SYSTEMTIME {
unsigned short wYear;
unsigned short wMonth;
unsigned short wDayOfWeek;
unsigned short wDay;
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
unsigned short wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
typedef struct _FILETIME {
unsigned long dwLowDateTime;
unsigned long dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
#endif
typedef struct cp56time2a {
u_short msec;
u_char min :6;
u_char res1 :1;
u_char iv :1;
u_char hour :5;
u_char res2 :2;
u_char su :1;
u_char mday :5;
u_char wday :3;
u_char month :4;
u_char res3 :4;
u_char year :7;
u_char res4 :1;
} cp56time2a ;
class CP56Time2a
{
private:
SYSTEMTIME stime;
bool valid;
bool genuine;
bool summer;
public:
CP56Time2a(unsigned char *data);
~CP56Time2a(void);
void GetTimeString(char *buf, size_t size);
FILETIME _GetFileTime(void);
SYSTEMTIME _GetSystemTime(void);
void ActualTimeToCP56Time(unsigned char *data);
void TimeToCP56Time2a(FILETIME *ft, unsigned char *data);
void TimeToCP56Time2a(SYSTEMTIME *st, unsigned char *data);
void CP56Time2aToTime(unsigned char *data, FILETIME *ft);
void CP56Time2aToTime(unsigned char *data, SYSTEMTIME *st);
};
#pragma pack (pop)
#endif // end __HT_TYPE_H

@ -0,0 +1,179 @@
/****************************************************************************
** File name : HTConfig.h
** Description : config parameter
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_CONFIG_H
#define __HT_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <list>
// 配置文件路径
#ifdef _WIN32
static const char HT_CONFIG_FILE[] = "../etc/ht_service.conf";
#else
static const char HT_CONFIG_FILE[] = "../etc/ht_service.conf" ;
#endif
class TConfig
{
public:
TConfig();
virtual ~TConfig();
static TConfig *getInstance();
// 读取配置文件参数
bool getIniConfig();
void showConfig();
// 设置本地服务器IP
void setLocalAddr(char *pszAddr);
// 获取本地服务器IP
char *getLocalAddr();
// 设置本地服务器端口
void setLocalPort(unsigned short iPort);
// 获取本地服务器端口
unsigned short getLocalPort();
// 设置远程服务器IP
void setRemoteAddr(char *pszAddr);
// 获取远程服务器IP
char *getRemoteAddr();
// 设置远程服务器端口
void setRemotePort(unsigned short iPort);
// 获取远程服务器端口
unsigned short getRemotePort();
void setRecvThreadNumber(unsigned int n) ; // 接收线程数
void setParseThreadNumber(unsigned int n) ; // 解析104线程数
void setOprationThreadNumber(unsigned int n) ; // 入库线程数
void setResponeThreadNumber(unsigned int n) ; // 应答线程数
unsigned int getRecvThreadNumber() ; // 接收线程数
unsigned int getParseThreadNumber() ; // 解析104线程数
unsigned int getOprationThreadNumber() ; // 入库线程数
unsigned int getResponeThreadNumber() ; // 应答线程数
// 配置数据库配置参数接口
unsigned int getdbPort() ;
unsigned int getdbMaxConnect();
unsigned int getdbMinConnect() ;
char *getdbHostIP() ;
char *getdbName() ;
char *getdbUserName() ;
char *getdbUserPass() ;
void setdbPort(unsigned int port);
void setdbMaxConnect(unsigned int max);
void setdbMinConnect(unsigned int min);
void setdbHostIP(char *pszDBHostIP);
void setdbName(char *pszDBName);
void setdbUserName(char *pszDBUserName);
void setdbUserPass(char *pszDBUserPass);
// socket 相关属性参数配置
void setFdLimit(unsigned int iCount);
unsigned int getFdLimit();
void setTimeout0(unsigned int t);
void setTimeout1(unsigned int t);
void setTimeout2(unsigned int t);
void setTimeout3(unsigned int t);
unsigned int getTimeout0();
unsigned int getTimeout1();
unsigned int getTimeout2();
unsigned int getTimeout3();
void setK(unsigned int k);
unsigned int getK();
void setW(unsigned int w);
unsigned int getW();
void setLogDebug(char yes);
void setLogError(char yes);
void setLogWarning(char yes);
void setLogPack(char yes);
void setLogConsole(char yes);
void setLogMessage(char yes);
char isLogDebug(void);
char isLogError(void);
char isLogWarning(void);
char isLogPack(void);
char isLogConsole(void);
char isLogMessage(void);
// version infomation functios
void setServerVersion(char *pver) ;
char *getServerVersion();
void setMonitor(bool bMonitor);
bool getMonitor();
// 读取配置文件函数
int iniGetString(const char *pszSection, const char *pszEntry, char *pszRetBuf, unsigned int uiBufLen);
private:
static TConfig *p_TConfig;
bool b_monitor_enable ; // 监控标志 true:启用 false: 不启用
// server version infomations
char m_version[32+1]; // format 2013.00.100
// database config parameter
char m_dbHostIP[16];
char m_dbName[16];
char m_dbUserName[16];
char m_dbUserPass[16];
unsigned int m_dbMaxConnect;
unsigned int m_dbMinConnect;
unsigned int m_dbPort;
char m_local_addr[16];
unsigned m_local_port;
char m_remote_addr[16] ;
unsigned int m_remote_port ;
// socket config
unsigned int m_fd_limit;
unsigned int t0,t1,t2,t3,uK,uW;
unsigned int m_recv_num;
unsigned int m_parse_num;
unsigned int m_opration_num;
unsigned int m_respone_num;
// logger
char m_logdebug; // debug logger
char m_logwarning; // warning logger
char m_logerror; // error logger
char m_logpack; // package print logger
char m_logconsole; // console print
char m_logmessage; // message print
};
#endif

@ -0,0 +1,68 @@
/****************************************************************************
** File name : HTConst.h
** Description : define const
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_CONST_H
#define __HT_CONST_H
// ASCI字符数字定义
#define KEY0 '0'
#define KEY1 '1'
#define KEY2 '2'
#define KEY3 '3'
#define KEY4 '4'
#define KEY5 '5'
#define KEY6 '6'
#define KEY7 '7'
#define KEY8 '8'
#define KEY9 '9'
// 数字定义
#define KEY_0 0x00
#define KEY_1 0x01
#define KEY_2 0x02
#define KEY_3 0x03
#define KEY_4 0x04
#define KEY_9 0x09
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
// use buffer size define
#define DEF_BUFFER_32 32
#define DEF_BUFFER_128 128
#define DEF_BUFFER_256 256
#define DEF_BUFFER_1K 1024
#define DEF_BUFFER_2K 2048
#define DEF_BUFFER_4K 4096
#define DEF_BUFFER_8K 8192
#define DEF_BUFFER_512K 1024*512
#define MAX_SLEEP_EMPTY 5 // ms
#define CHANNEL_DOWN 1 // MEC下行通道UDP
#define CHANNEL_UP 0 // MEC上行通道UDP
#define MAX_FLT_EXTERN 24 // 最大内部报文扩展项个数
// 809平台间报文类型
#define PALT_PKG_QUERY 0 // 平台查岗
#define PALT_PKG_MESG 1 // 平台间报文消息
// 来源
#define MSG_SOURCE_MARGE 0 // 上级监管平台
#define MSG_SOURCE_LOACL 1 // 企业平台
#define HT_INVALID_VALUE 0x7FFFFFFF // 无效值
#endif // end __HT_CONST_H

@ -0,0 +1,379 @@
/****************************************************************************
** File name : HTDataStruct.h
** Description : define data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_DATA_STRUCT_H
#define __HT_DATA_STRUCT_H
#pragma pack (push ,1)
#define DEF_EQM_CODE_SIZE 32+1 // 设备编码eqm_code最大长度
//#define _SITE_ID_TYPE_INT // 站点ID数据类型定义
#ifdef _SITE_ID_TYPE_INT
typedef unsigned int htype;
#else
typedef unsigned char* htype;
#endif
typedef struct {
unsigned char status; // 链接状态 0:非正常 1:正常
int udp_fd; // 与MEC的上行通道套接字fd
tint64 online_time; // 登陆时间
tint64 last_time; // 离线/退出时间
struct sockaddr_in staddr; // 对方地址
}ST_UDP_CONN;
// 链路管理数据结构
typedef struct {
bool isConnect; // true: connected false: not connected
int listenid; // listen handle
int sockid; // socket connect handle
time_t last_time; // last send/recv time
bool is_yk_ack ; // 是否收到遥控信号
bool b_Signal; // 遥信量变化 false: 无变化 true:有变化,则需记录一条记录
time_t stime; // 遥信信号变化时间否则为0
time_t etime; // 结束时间
time_t lastTime; // 最近一次入库时间
time_t last_yx_time;
time_t last_yc_time;
unsigned long m_gis_fault_count; // gis故障次数
//unsigned long m_gis_count; // gis开合次数
bool m_gis_change; // 断路器断开时,记录入库
char m_iec_warn_time[24]; // IEC子站异常时间
unsigned short usSendNo; // 发送序号
unsigned short usRecvNo; // 接收序号
int TxCounter;
int RxCounter;
int LastAckTx;
int LastAckRx;
int t0; // time-out of connection establishment (reconnection) TCP连接建立的超时时间
int t1; // time-out of send or test APDUs (wait ack). RTU服务器端启动U格式测试过程后等待U格式测试应答的超时时间
int t2; // time-out for ack in case of no data messages (T2 < T1). S格式的超时时间
int t3; // time-out for sending TESFR in case of long idle state. 没有实际的数据交换时任何一端启动U格式测试过程的最大间隔时间
int k; // maximum difference N(R) and N(S)
int w; // lastest ack after receiving W I-Format message.
unsigned short usISUType; // 0,2=I ; 1=S ; 3=U
//int timer_Connect;
int timer_t0; // T0 param
int timer_Confirm; // associated of T1 param
int timer_t1; // T1 param
int timer_S_Ack; // associated of T2 param
time_t timer_t2; // T2 param
bool timer_S_Ackflag;
time_t timer_t3; // T3 param
bool timer_U_Testflag;
time_t time_action; // 总召间隔请求时间
}ST_IEC104_CTRL;
typedef struct {
unsigned char start; // 起始字节
unsigned char len; // 帧长度
unsigned char cntl1; // 控制域1-4
unsigned char cntl2;
unsigned char cntl3;
unsigned char cntl4;
}ST_APCI;
typedef struct { // 数据单元标识
unsigned char type; // 类型标识
unsigned char qual; // 可变结构限定词
unsigned char tx_cause1; // 传送原因2字节根据主站配置
unsigned char tx_cause2;
unsigned char commom_asdu1; // 公共地址(2字节)根据主站配置
unsigned char commom_asdu2;
}ST_ASDU_HEADER;
typedef struct {
ST_ASDU_HEADER header; // 数据单元标识
unsigned char data[243]; // 信息体
}ST_ASDU;
typedef struct {
ST_APCI apci;
ST_ASDU asdu;
}ST_IEC_APDU;
typedef struct
{
int iLength ; // 接收长度
unsigned short usISUType; // 0,2=I ; 1=S ; 3=U
unsigned short usSendNo; // 发送序号
unsigned short usRecvNo; // 接收序号
unsigned char *pszBuff; // 接收数据
}ST_RECVPKG ;
/*
typedef struct {
unsigned short usISUType ; // 0,2=I ; 1=S ; 3=U
unsigned short usLen ; // data length
unsigned short usSendNo; // 发送序号
unsigned short usRecvNo; // 接收序号
unsigned int LastAckSendNo; // last send number
unsigned int LastAckRecvNo; // last recv number
ST_ASDU_HEADER stAsduHead; // ASDU Header
unsigned int uiInfoAddr; // info body addr,3(byte)
unsigned int uiLastAckTx; // last respone send number
}ST_IEC104_INFO;
*/
// single point information w/quality
struct SIQ104{
unsigned char spi : 1, // off=0 / on=1
rs1 : 1, // reserve
rs2 : 1, // reserve
rs3 : 1, // reserve
bl : 1, // not blocked=0 / blocked=1
sb : 1, // not substituted=0 / substituted=1
nt : 1, // topical=0 / not topical=1
iv : 1; // valid=0 / not valid=1
};
// quality descriptor
struct QDS104{
unsigned char ov : 1, // no overflow=0 / overflow=1
rs1 : 1, // reserve
rs2 : 1, // reserve
rs3 : 1, // reserve
bl : 1, // not blocked=0 / blocked=1
sb : 1, // not substituted=0 / substituted=1
nt : 1, // topical=0 / not topical=1
iv : 1; // valid=0 / not valid=1
};
// single point value
struct SP104{
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
struct SIQ104 siq;
};
// single point value w/time tag CP56Time2a
struct SP104_T{
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
struct SIQ104 siq;
unsigned char time[7];
};
// short floating point value
struct SFP104{
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
//float value;
unsigned char val[4];
struct QDS104 qds;
};
// short floating point value
struct SFP104V{
unsigned char val[4];
struct QDS104 qds;
};
// short point value
struct SH104{
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
unsigned char val[2];
struct QDS104 qds;
};
// short point value
struct SHP104{
unsigned char val[2];
struct QDS104 qds;
};
// short floating point value w/time tag CP56Time2a
struct SFP104_T{
unsigned char addr0;
unsigned char addr1;
unsigned char addr2;
unsigned char val[4];
struct QDS104 qds;
unsigned char time[7];
};
// GIS负荷计算表结构定义iec_break_param
typedef struct {
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char system_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char wstate; // 工作状态 1:发电 2:抽水 3:空闲
unsigned char is_close; // 断开状态 0:分 1:合
unsigned char is_fault; // 是否故障 1:故障 0:正常
float faild_rate; // 发生故障率%
time_t d_time; // 发生时间
double abort_current; // 断开电流(A)
double abort_voltage; // 断开电压V
}ST_IEC_GISBREAK_TABLE;
// 变压器负荷计算表结构定义iec_bydwork_param
typedef struct {
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char system_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char state; // 状态类型: 1-发电状态 2抽水状态 3空闲状态
unsigned char is_fault; // 主变是否故障 1:故障 0:正常
time_t start_time; // 发电/抽水开始时间
time_t stop_time; // 发电/抽水结束时间
time_t real_time; // 发生时间
double voltage; // 高/低压出口电压(kV)
double current; // 高/低压出口电流(A)
}ST_IEC_BYQWORK_TABLE;
// 变压器运行工况表结构定义transformer_read_table
typedef struct {
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char system_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char wstate; // 工作状态1-发电状态 2抽水状态 3空闲状态
time_t chkTime; // 监测时间
#if 0
double dcurJkyl; // 冷却水进口压力值
double dcurCkyl; // 冷却水出口压力值
double dCoolWaterTempEntry; // 冷却水进口温度
double dCoolWaterTempOuter; // 冷却水出口温度
//2020-05-23 add
double dOilPressEntry; // 变压器油进口油压力(MPa)
double dOilPressOuter; // 变压器油出口油压力(MPa)
double dOilTempEntry; // 变压器油进口温度
double dOilTempOuter; // 变压器油出口温度
double dOilTemperature; //主变本体油温点位
double dOilPosition; //主变本体油位点位
double dOilTopTemp; //主变顶层油温点位
double dOilPillowLevel; //主变油枕油位点位
double dWindingTemp; //主变绕组温度点位
#else
char dcurJkyl[16]; // 冷却水进口压力值
char dcurCkyl[16]; // 冷却水出口压力值
char dCoolWaterTempEntry[16]; // 冷却水进口温度
char dCoolWaterTempOuter[16]; // 冷却水出口温度
char dOilPressEntry[16]; // 变压器油进口油压力(MPa)
char dOilPressOuter[16]; // 变压器油出口油压力(MPa)
char dOilTempEntry[16]; // 变压器油进口温度
char dOilTempOuter[16]; // 变压器油出口温度
char dOilTemperature[16]; //主变本体油温点位
char dOilPosition[16]; //主变本体油位点位
char dOilTopTemp[16]; //主变顶层油温点位
char dOilPillowLevel[16]; //主变油枕油位点位
char dWindingTemp[16]; //主变绕组温度点位
#endif
}ST_IEC_BYQREAD_TABLE;
// 入库队列
typedef struct
{
unsigned char ctype; // 类型:1-运行工况 2:断路器数据 3:变压器数据
unsigned int iLength; // 数据长度
unsigned char *pData; // 数据ST_MASRTE_PARAM |ST_BREAKER_PARAM|ST_WORK_PARAM
}ST_DB_DATA;
// 变压器工作数据,通过104获取。
typedef struct {
unsigned char stype; // 状态类型: 1-发电状态 2抽水状态 3空闲状态
time_t start_time; // 发电/抽水开始时间
time_t stop_time; // 发电/抽水结束时间
double voltage; // 高/低压出口电压(v)
double current; // 高/低压出口电流(A)
double dcurYWei; // 最近油位值
double dcurYWen; // 最近油温值
double dcurJkyl; // 最近冷却水进口压力值
double dcurCkyl; // 最近冷却水出口压力值
}ST_IEC104_BYQ_DATA;
// 变压器设备对应关系、阈值缓存记录
//typedef struct {
//#ifdef _SITE_ID_TYPE_INT
// unsigned int SiteID; // 站点ID
//#else
// unsigned char SiteID[DEF_EQM_CODE_SIZE]; // 站点ID
//#endif
// unsigned char szSiteCode[DEF_EQM_CODE_SIZE]; // 物理站点唯一编码
// unsigned char szEqmCode[DEF_EQM_CODE_SIZE]; // 系统设备唯一编码
// unsigned char szSersorID[20]; // sersorid唯一编码
// double dYWei; // 油位阈值
// double dYWen; // 油温阈值
// double dJkyl; // 冷却水进口压力阈值
// double dCkyl; // 冷却水出口压力阈值
// ST_IEC104_BYQ_DATA stLastData; // 变压器最近一次104上传的数据
//}ST_BYQ_CACHE;
// 断路器104数据结构
//typedef struct {
// unsigned char is_fault; // 是否故障 1否 2
// time_t record_date; // 发生时间
// double voltage; // 断开电压(V)
// double current; // 断开电流(A)
// double failed_rate; // %电流故障百分比%
//}ST_IEC104_GIS_DATA;
// GIS设备对应关系、阈值缓存记录
//typedef struct {
//#ifdef _SITE_ID_TYPE_INT
// unsigned int SiteID; // 站点ID
//#else
// unsigned char SiteID[DEF_EQM_CODE_SIZE]; // 站点ID
//#endif
// unsigned char szEqmCode[DEF_EQM_CODE_SIZE]; // 设备唯一编码
// ST_IEC104_GIS_DATA stLastData; // 断路器最近一次104上传的数据
//}ST_GIS_IEC104_DATA;
// GIS设备外挂对应关系、阈值缓存记录
//typedef struct {
//#ifdef _SITE_ID_TYPE_INT
// unsigned int SiteID; // 站点ID
//#else
// unsigned char SiteID[DEF_EQM_CODE_SIZE]; // 站点ID
//#endif
// unsigned char szSersorID[20]; // sersorid唯一编码
// unsigned char szEqmCodeID[18]; // 设备唯一编码
// unsigned char name_des[128]; // 设备名称,描述
// double dNum ; // GIS放电电流(mA)
//}ST_GIS_CACHE;
// BLQ设备对应关系、阈值缓存记录
//typedef struct {
//#ifdef _SITE_ID_TYPE_INT
// unsigned int SiteID; // 站点ID
//#else
// unsigned char SiteID[DEF_EQM_CODE_SIZE]; // 站点ID
//#endif
// unsigned char szSersorID[20]; // sersorid唯一编码
// unsigned char szEqmCodeID[18]; // 设备唯一编码
// unsigned char name_des[128]; // 设备名称,描述
// double dMaxDL; // 避雷器放电电流图片识别阈值
//}ST_BLQ_CACHE;
#pragma pack (pop)
#endif // end

@ -0,0 +1,100 @@
/****************************************************************************
** File name : HTDatabase.h
** Description : define database api
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_DATABASE_H
#define __HT_DATABASE_H
#include "HTPublic.h"
#include "HTDataStruct.h"
#include "mysql.h"
#ifdef _WIN32
//#pragma comment(lib,"ociliba.lib")
#pragma comment(lib,"libmysql.lib")
#endif
typedef std::list<MYSQL *> CONNECTION_HANDLE_LIST;
typedef std::list<MYSQL *>::iterator ITER_CONNECTION_HANDLE_LIST;
#define CONNECTION_NUM 10 //同时打开的连接数
class CDBMySQL
{
public:
CDBMySQL();
CDBMySQL(const char *host, const char *user, const char *password, const char *db, unsigned int port=3306);
virtual ~CDBMySQL();
public:
bool dbConnectPool(); //连接数据库
void dbFreeConnectPool() ; //释放链接资源
bool dbAutoCommit(MYSQL *pMysql, bool bStart); // 开始事务处理
bool dbCommit(MYSQL *pMysql);
bool InsertRecordBitch(const char pszSql[][256], int count);
bool AddInsertRecord(MYSQL *pHandle, const char *szSql);
MYSQL_RES* SelectRecord(const char *szSql); //选择记录,返回结果集
bool SelectDB(const char *szDB); //选择数据库
bool UpdateRecord(const char *szSql); //更新记录
bool InsertRecord(const char *szSql); //插入记录
bool DelRecord(const char *szSql); //删除记录
bool IsEnd(MYSQL_RES *myquery); //是否最后
void SeekData(MYSQL_RES *myquery, int offset); //查找指定数据
void FreeRecord(MYSQL_RES *myquery); //释放结果集
unsigned int GetFieldNum(MYSQL_RES *myquery); //得到字段数
MYSQL_ROW GetRecord(MYSQL_RES *myquery); //得到结果(一个记录)
my_ulonglong GetRowNum(MYSQL_RES *myquery); //得到记录数
char* getLastError(MYSQL* pMySql); //输出错误信息
char* GetState(); //服务器状态
char* GetServerInfo(); //服务器信息
int GetProtocolInfo(); //协议信息
char* GetHostInfo(); //主机信息
char* GetClientInfo(); //客户机信息
char* GetFieldName(MYSQL_RES *myquery, int FieldNum); //字段名
bool LockTable(const char *TableName, const char *Priority); //对特定表加锁
bool UnlockTable(); //解锁
bool SetCharset();
//int CreateDB(char *db); //创建数据库,返回错误信息
//int DropDB(char *db); //删除数据库,返回错误信息
MYSQL* GetIdleMySql(); //提取一个空闲句柄供使用
void SetIdleMysql(MYSQL* pMySql); //从使用队列中释放一个使用完毕的句柄,插入到空闲队列
static CDBMySQL* Instance();
public:
//MYSQL m_mysql; //数据库连接句柄
MYSQL_ROW m_row; //记录集(单行)
MYSQL_FIELD *m_field; //字段信息(结构体)
//创建两个队列
CONNECTION_HANDLE_LIST m_lsBusyList; //正在使用的连接句柄
CONNECTION_HANDLE_LIST m_lsIdleList; //未使用的连接句柄
mutex m_csList;
private:
static CDBMySQL* p_dbHandle ;
char m_host[20]; //主机
char m_user[20]; //用户名
char m_password[20]; //密码
char m_db[20]; //数据库名
unsigned int m_port; //端口
unsigned int m_min; // 链接数
};
#endif // __HT_DATABASE_H

@ -0,0 +1,44 @@
/****************************************************************************
** File name : HTError.h
** Description : define error code
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_ERROR_H
#define __HT_ERROR_H
#define RET_OK 0
#define RET_FAIL -1
#define RET_IPPORT_INVALID -2 // IP地址或端口无效
#define RET_UDP_BIND_PORT -3 // UDP绑定端口错误
#define RET_LENGTH_INVALID -4 // 数据长度无效
#define RET_VALUE_INVALID -5 // 域值无效
#define RET_TYPE_INVALID -6 // 业务类型无效
#define RET_CALLOC_FAIL -7 // 申请内存失败
#define RET_SUB_ID_INVALID -8 // 域ID标识无效/不支持的ID标识码
#define RET_CALL_OCI_FAILED -9 // OCI调用失败
#define RET_NOT_FOUND_RECORD -10 // 无原请求业务流水
#define RET_ERROR_AUTHID -11 // 无效接入码
#define RET_UDP_STATUS_EXP -12 // UDP链接状态异常
#define RET_NOT_EXTERN_PACK -13 // 无扩展报文
#define RET_NOT_FOUND_ACCESSID -14 // 没有检索到接入码
#define RET_TERM_NOT_ONLINE -15 // 终端不在线
#define RET_SUB_COMMAND_INVALID -16 // 采集数据的子命令无效
#define RET_MAJOR_CONN_ERR -17 // TCP主链路状态错误
#define RET_NOT_FILE_EXIST -18 // 文件不存在
#define RET_NOT_DATA -19 // 采集行驶记录无数据
#define RET_SET_ERROR_PIC -20 // 插入拍照下发指令记录失败
#define RET_SERVER_ID_ERR -21 // 连接服务器名称无效
#define RET_JT809_VERSION -22 // 数据库配置了无效的JT809协议版本号
#define RET_JT808_VERSION -23 // 808内部报文协议类型无效
#define RET_JT809_CRC_ERROR -24 // CRC16校验错误
#define RET_LINK_CHECK_ERROR -25 // 链路校验码错误
#define RET_RECORD_ORG_ID_NULL -26 // 记录仪ID或企业ID为空
#endif // end __HT_ERROR_H

@ -0,0 +1,120 @@
/****************************************************************************
** File name : HTGolbal.h
** Description : global variable define
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#pragma warning (disable:4786)
#ifndef __HT_GLOBAL_H
#define __HT_GLOBAL_H
#include "HTType.h"
#include "HTConst.h"
#include "HTMutex.h"
#include "HTPublic.h"
#include "HTLogger.h"
#include "HTConfig.h"
#include "HTDatabase.h"
#include "HTDataStruct.h"
#include "HTHP104Table.h"
#include "HTMemCacheData.h"
#include "HTInitUtils.h"
#include "HTCP56Time.h"
#include "HTError.h"
#include "HTTcpSocket.h"
#include "HTIEC104.h"
#include "HTThread.h"
#include "HTImageBusi.h"
#include "HTOpencvImg.h"
#include "HTTestOpencv.h"
#include "HTUnit.h"
#include "HTVersion.h"
#include <list>
#include <map>
#include <vector>
#include <iostream>
#define _HT_OPENCV_APP // 图片分析处理程序
#define _HT_IEC104_APP // IEC104通讯程序
#define _DEF_HMF_VOLTAGE // 黑麋峰高压侧电流计算
#define _DEF_DB_CHANGERATE // 启用偏差率入库功能,否则以设定的间隔时间入库
using namespace std;
//#define _CRT_SECURE_NO_WARNINGS 1
extern int g_Running;
extern TConfig g_TConfig;
extern TTcpSocket g_Tcp;
extern ST_IEC104_CTRL g_IecCtrl; // socket linker info and status
extern mutex g_IecCtrl_mutex; // socket linker on mutex
extern map<string, ST_BYQWORK_STATUS> g_map_work; // 主变工作状态缓存
extern mutex g_map_work_mutex; // 主变工作状态缓存队列锁
//extern map<string,ST_BYQ_CACHE> g_map_byq; // 变压器缓存数据
extern map<string, ST_BYQ_RUN_STATE_THRESHOLD> g_map_thres_byq; // 变压器缓存数据
extern mutex g_map_byq_mutex; // 变压器缓存数据信息队列锁
//extern map<string,ST_GIS_CACHE> g_map_gis; // GIS缓存数据
//extern mutex g_map_gis_mutex; // GIS缓存数据信息队列锁
extern multimap<string, ST_DEV_RELATION> g_map_relation; // 主设备与外挂设备关系
extern mutex g_map_relation_mutex; // GIS缓存数据信息队列锁
//extern map<string, ST_GIS_IEC104_DATA> g_map_gis_104; // GIS最近一次104上传数据缓存
//extern mutex g_map_gis_104_mutex;
//extern map<string, ST_BLQ_CACHE> g_map_blq; // BLQ缓存数据
//extern mutex g_map_blq_mutex; // BLQ缓存数据信息队列锁
extern map<unsigned int, ST_IECPOINT_TABLE> g_map_iec; // 104报文解析缓存数据
extern mutex g_map_iec_mutex; // 104报文解析缓存数据信息队列锁
extern map<unsigned int, ST_SADR_MATCH> g_map_sadr; // 点表匹配关系
extern mutex g_map_sadr_mutex;
extern map<string, ST_IMG_THRESHOLD> g_map_img_thres; // 图片识别阈值
extern mutex g_map_img_thres_mutex;
//extern list<ST_LIST_MONITOR> g_list_monitor; // 监控消息数据队列
//extern mutex g_list_monitor_mutex;
extern map<string, ST_DEVICE_TIME_STAT> g_map_dev_time_stat;
extern mutex g_map_dev_time_stat_mutex;
extern map<unsigned int, ST_BREAK_EQM_CODE> g_map_gis_state; // 断路器状态位与电流电压关系匹配表
extern mutex g_map_gis_state_mutex;
extern int g_seqno; // 与MEC之间交换的流水号
extern mutex g_seq_mutex; // 流水号
extern pthread_t thread_handle_monitor; // 监控线程句柄
extern pthread_t thread_handle_parse; // 104报文解析线程
//extern pthread_t thread_handle_setdb; // 入库线程
//extern pthread_t thread_handle_getdata; // 数据提取线程
extern pthread_t thread_handle_timer; // 应答线程
extern pthread_t thread_handle_client; // 客户端链接线程
extern pthread_t thread_handle_warning; // 报警处理及入库线程句柄
extern pthread_t thread_handle_origin; // 原始数据如何线程句柄
extern pthread_t thread_handle_pingce; // IEC104评测数据入库线程句柄
extern pthread_t thread_handle_gishold; // 断路器断开数据入库线程句柄
extern pthread_t thread_handle_active; // 心跳线程
extern pthread_t thread_handle_linkmgr; // 链路管理线程
extern pthread_t thread_handle_cache; // 内存同步线程句柄
extern pthread_t thread_handle_opecvimg; // 图片识别线程句柄
#endif // end __HT_GLOBAL_H

@ -0,0 +1,144 @@
/****************************************************************************
** File name : HTHP104Table.h
** Description : define data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HP104_TABLE
#define __HP104_TABLE
static const char IEC_CONFIMG_FILE[] = "../etc/ht_iec104.conf";
#pragma pack (push ,1)
// 一个单元的信息体
typedef struct {
int count; // 索引,0开始
unsigned int objaddr; // 信息对象地址(3)
unsigned int objval; // 值域
}ST_OBJVAL;
// 变压器设备唯一编码
typedef struct _BYQ_EQM_CODE {
unsigned char szEqmCode[DEF_EQM_CODE_SIZE]; // 设备编码,16位
unsigned int uiHighVoltage; //发电状态: 主变高压侧电压点位
unsigned int uiHighCurrent; //发电状态: 主变高压侧电流点位
unsigned int uiLowVoltage; //抽水、空闲状态: 主变低压侧电压点位
unsigned int uiLowCurrent; //抽水、空闲状态: 主变低压侧电流点位
unsigned int uiCoolWaterPressEntry; //主变冷却水进口压力点位
unsigned int uiCoolWaterPressOuter; //主变冷却水出口压力点位
unsigned int uiCoolWaterTempEntry; //主变冷却水进口温度点位
unsigned int uiCoolWaterTempOuter; //主变冷却水出口温度点位
unsigned int uiOilPressEntry; //主变油进口压力点位
unsigned int uiOilPressOuter; //主变油出口压力点位
unsigned int uiOilTempEntry; //主变油进口温度点位
unsigned int uiOilTempOuter; //主变油出口温度点位
unsigned int uiOilTemperature; //主变本体油温点位
unsigned int uiOilPosition; //主变本体油位点位
unsigned int uiOilTopTemp; //主变顶层油温点位
unsigned int uiOilPillowLevel; //主变油枕油位点位
unsigned int uiWindingTemp; //主变绕组温度点位
time_t stime;
time_t etime;
}ST_BYQ_EQM_CODE;
// 设备工作时间及状态记录
typedef struct _DEVICE_TIME_STAT {
unsigned char sys_code[DEF_EQM_CODE_SIZE]; // sys_code,主设备ID,对应busi_site_tree.system_code
unsigned char desct[DEF_BUFFER_256]; // sys_code,主设备ID,对应busi_site_tree.system_code
time_t usTime; // 最近一次记录时间
unsigned char wstate; // 工作状态1-发电状态 2抽水状态 3空闲状态
}ST_DEVICE_TIME_STAT;
// 断路器设备唯一编码
typedef struct _BREAK_EQM_CODE {
unsigned char szEqmCodeA[DEF_EQM_CODE_SIZE]; // 设备编码,16位
unsigned char szEqmCodeB[DEF_EQM_CODE_SIZE]; // 设备编码,16位
unsigned char szEqmCodeC[DEF_EQM_CODE_SIZE]; // 设备编码,16位
unsigned int uiStateSadr; //断开状态点位地址 对应值含义=1合 0
unsigned int uiAbortVoltage; //断开电压点位
unsigned int uiAbortCurrent; //断开电流点位
}ST_BREAK_EQM_CODE;
// IEC104协议基础配置信息
typedef struct _IEC104_CONF
{
unsigned int save_internal; // 104时间保存间隔时间(s)
unsigned int iec_byq_count; // 变压器数量
unsigned int iec_break_count; // 断路器数量
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned short iec_global_addr; // 公共地址
unsigned int yx_start_addr; // YX 0x0001- 遥信起始地址, 十进制数
unsigned int yx_stop_addr; // YX 0x1000- 遥信结束地址, 十进制数
unsigned int jb_start_addr; // JB 0x1001- 继电保护起始地址, 十进制数
unsigned int jb_stop_addr; // JB 0x4000- 继电保护结束地址, 十进制数
unsigned int yc_start_addr; // YC 0x4001- 遥测起始地址, 十进制数
unsigned int yc_stop_addr; // YC 0x5000- 遥测起始地址, 十进制数
ST_BYQ_EQM_CODE *pstByqCode; // 变压器设备系统唯一编码
ST_BREAK_EQM_CODE *pstBrkCode; // 断路器设备系统唯一编码
}ST_IEC104_CONF;
// 点表地址匹配关系
typedef struct {
unsigned int group; // 组号
unsigned int btype; // 电流、电压......
unsigned int sadr; // 相关联的其他sadr列表
}ST_MATCH_LIST;
typedef struct{
//unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 设备编码
unsigned char eqm_type; // 1:主变 2:GIS 3:测温 4:避雷器
unsigned int count; // *psadr的数量
ST_MATCH_LIST *psadr; //ST_MATCH_LIST[]
}ST_SADR_MATCH;
// 解析104报文的值缓存区、点表配置信息,表iec_point_conf
typedef struct _IECPOINT_TABLE
{
unsigned char stype; // 地址类型 1:遥信 2:遥测
unsigned char cval; // 遥信值
unsigned int sno; // 起始地址偏移量
unsigned int sadr; // 信息体地址map.key
double fval; // 遥测值
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // eqm_code,主设备ID,对应busi_site_tree.id
unsigned char sys_code[DEF_EQM_CODE_SIZE]; // sys_code,主设备ID,对应busi_site_tree.system_code
unsigned char fieldname[DEF_EQM_CODE_SIZE * 2]; // 阈值字段名称,transformer_runing_status_threshold表字段
unsigned char isget; // 评测字段提取标志,YX:{1=总开关状态 2=发电状态 3=抽水状态 4=事故状态} YC:{1=提取 0:不提取}
unsigned short unit; // 104协议数据单位
unsigned short sysunit; // 系统固定的字段单位,参与评测数据
double devrate; // 偏差率,当值在±之间时,保存数据
unsigned char eqm_type; // 设备类型 1:主变 2:GIS 3:测温 4:避雷器
unsigned char warnFlag; // 告警判断, =1:>预警值时告警 =2:<预警值时告警(压力) 油位如何告警(最低/高)
time_t dtime; // 告警时间
unsigned char wstate; // 工作状态1-发电状态 2抽水状态 3空闲状态
unsigned char bfault; // 主变事故状态0-正常 1-事故状态
unsigned char poidesc[DEF_BUFFER_256]; // 点表字段描述
}ST_IECPOINT_TABLE;
/* isget:
1: 2: 3: 4:
5: 6: 7: 8:
9: 10: 11:/ 12:/
13: 14: 15:GIS 16:GIS 17:
18: 19: GIS
// unit:
1:kV() 2:V() 3:kA() 4:A() 5:mA() 6:() 7:Pa() 8:KPa() 9:MPa() 10:pF()
11:pC() 12:dB() 13:μL() 14:L() 15:m/s(/) 16:rpm&r/min(/)
*/
#pragma pack (pop)
#endif // end

@ -0,0 +1,97 @@
/****************************************************************************
** File name : HTIEC104.h
** Description : define 104 struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_IEC104_H
#define __HT_IEC104_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define CMD_START_HEAD 0x68
// 激活命令
#define CMD_STARTDT 0x04
#define CMD_STOPDT 0x10
#define CMD_TESTFR 0x40
// 确认命令
#define CMD_STARTC 0x08
#define CMD_STOPC 0x20
#define CMD_TESTC 0x80
//总召指令
#define CMD_CTL_64H 0x64 // type=总召激活
#define MIN_APDU_LENGTH 6 // min lengtg = 6byte, APCI
#define MAX_ASDU_LENGTH 249
#define YX_STAT_OPEND 0 // 开关状态: 0--开闸
#define YX_STAT_CLOSE 1 // 开关状态: 1--合闸
// 心跳
#define CMD_ACTIVE_PACKAGE "\x68\x04\x40\x00\x00\x00"
class CIEC104
{
public:
CIEC104() ;
~CIEC104() ;
private:
protected:
};
void IEC104EnvFree();
void IEC104EnvLoad();
void UpdateLastTime();
void *thread_listen_proc(void *arg);
void *thread_client_proc(void *arg);
void *thread_warn_proc(void *arg);
void *thread_origin_proc(void *arg);
void * thread_pingce_proc(void * arg);
void *thread_recv_proc(void *arg) ;
void *thread_active_proc(void *arg);
void *thread_parser_proc(void *arg);
void *thread_Timer_proc(void *arg);
void *thread_cache_proc(void *arg) ; // 同步内存数据线程
//void *thread_setdb_proc(void *arg); // 数据入库线程
//void *thread_getdata_proc(void *arg);
void *thread_origin_proc(void *arg); // 原始数据入库现场
void *thread_gis_hold_proc(void * arg);
// 刷新机组的工作状态,1发电、2抽水、3空闲
unsigned char getDevWorkState(ST_IECPOINT_TABLE &stIec);
unsigned char getDevFaultState(ST_IECPOINT_TABLE &stIec);
//
////// 获取BYQ设备对应关系及阈值
//bool bGetByqCacheRelation(unsigned char *pszSersorid, ST_BYQ_CACHE *pstData);
////
////// 获取GIS设备对应关系及阈值
//bool bGetGisCacheRelation(unsigned char *pszSersorid, ST_GIS_CACHE *pstData);
////
////// 获取BLQ设备对应关系及阈值
//bool bGetBlqCacheRelation(unsigned char *pszSersorid, ST_BLQ_CACHE *pstData);
bool bSetBYQPointValueByAddr(const char *pszEqmCode, float value);
#ifdef __cplusplus
}
#endif
#endif // end

@ -0,0 +1,42 @@
/****************************************************************************
** File name : HTImageBusi.h
** Description : define memory data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_IMAGE_BUSI_H
#define __HT_IMAGE_BUSI_H
#pragma pack (push ,1)
//图片识别阈值缓存区
typedef struct
{
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 主设备编码/主变/GIS/避雷器
unsigned char system_code[DEF_EQM_CODE_SIZE];// 系统设备编码
unsigned char sensor_id[DEF_EQM_CODE_SIZE]; // Sensor Code,map key
unsigned char desc[DEF_BUFFER_256]; // 对应sensor code的描述
unsigned char eqm_type; // 设备类型 1:主变 2:GIS 3:测温柜 4:避雷器
//unsigned char wstate; // 工作状态 1:发电状态 2抽水状态 3空闲状态
unsigned char phase; // 相位 O:全相 1:A相 2:B相 3:C相
double value[3]; // 阈值,index=0:发电状态阈值 =1:抽水状态阈值 =2:空闲状态阈值
}ST_IMG_THRESHOLD;
// 加载图片阈值
void vLoadImageThreshold();
void vPrtImageThreshold(void);
// 根据sensor_id获取阈值
bool getImageThresholdValuse(const char *sensor_id, ST_IMG_THRESHOLD &pstThresdhold);
#pragma pack (pop)
#endif // end

@ -0,0 +1,32 @@
/****************************************************************************
** File name : HTInitUtils.h
** Description : Defines service initialization API
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_INIT_UTILS_H
#define __HT_INIT_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
// 初始化服务运行环境
int loadServiceEvent();
void reloadServiceEvent(int platform_id);
int unLoadServiceEvent();
int get_seqno(void);
#ifdef __cplusplus
}
#endif
#endif // end __HT_INIT_UTILS_H

@ -0,0 +1,75 @@
/****************************************************************************
** File name : HTLogger.h
** Description : logger function define
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_LOGGER_H
#define __HT_LOGGER_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// logger config parameter
#ifdef _WIN32
static const char *DEF_LOG_PATH_NAME = "..\\log" ; //日志文件目录名
static const char *DEF_RUN_INFO_PATH = "..\\run" ; // 服务运行状态日志目录
#else
static const char *DEF_LOG_PATH_NAME = "../log" ; //日志文件目录名
static const char *DEF_RUN_INFO_PATH = "../run" ; // 服务运行状态日志目录
#endif
// 打印报文类型,日志
#define PRT_PACK_SEND 0 // 打印发送报文类型
#define PRT_PACK_RECV 1 // 打印接收报文类型
#define PRT_PACK_DATA 2 // 打印报文
#define DEF_LOG_FILESZIE 1048576*50 /* logfile size define 50M byte */
#ifdef LOG_DEBUG
#undef LOG_DEBUG
#endif
#define __LOG_DEBUG 0 // 跟踪日志
#define LOG_DEBUG __LINE__, _FILE_, __LOG_DEBUG
#ifdef LOG_WARNG
#undef LOG_WARNG
#endif
#define __LOG_WARNG 1 // 告警日志
#define LOG_WARNG __LINE__, _FILE_, __LOG_WARNG
#ifdef LOG_ERROR
#undef LOG_ERROR
#endif
#define __LOG_ERROR 2 // 错误日志
#define LOG_ERROR __LINE__, _FILE_, __LOG_ERROR
#ifdef LOG_PACK
#undef LOG_PACK
#endif
#define __LOG_PACK 3 // 报文日志
#define LOG_PACK __LINE__, _FILE_, __LOG_PACK
// 日志记录相关函数
void vInitLogMutex(void);
void vFreeLogMutex(void);
void vPrtLogMsg(int line, const char *pszFileName, char logLevel, int iCode, ...);
void vPrtLogHex(int line, const char *pszFileName, char logLevel, int sockid, /* unsigned short msg_id, */
char pszMsgType, unsigned char *pusMsg,int uiMsgLen);
#ifdef __cplusplus
}
#endif
#endif // __HT_LOGGER_H

@ -0,0 +1,110 @@
/****************************************************************************
** File name : HTMemCacheData.h
** Description : define memory data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_MEM_CACHE_DATA_H
#define __HT_MEM_CACHE_DATA_H
#pragma pack (push ,1)
// 变压器三种工作状态下的阈值,运行工况阈值的字典
typedef struct
{
double value; // 阈值
char field[64]; // 阈值字段名称,对应阈值表中的字段名称
}ST_STAT_FIELD;
#define MAX_RUN_STATUS_COUNT 15 // 一个主变的最大运行工况阈值数量
typedef struct {
int fnum; // 阈值个数
ST_STAT_FIELD stField[MAX_RUN_STATUS_COUNT];
}ST_STAT_THRESHOLD;
// 变压器运行工况阈值缓存信息体
typedef struct{
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 主设备ID,对应表busi_site_tree.id,map.key
unsigned char system_code[DEF_EQM_CODE_SIZE]; // 系统设备编码,strkey
unsigned char dev_name[DEF_EQM_CODE_SIZE * 2]; // 设备名称
unsigned char wstate; // 当前设备工作状态 1-发电状态 2抽水状态 3空闲状态
ST_STAT_THRESHOLD stThreashod[3]; // 0-发电状态 1抽水状态 2空闲状态
}ST_BYQ_RUN_STATE_THRESHOLD;
// 主变与其他主设备关联关系
typedef struct{
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char m_eqm_code[DEF_EQM_CODE_SIZE]; // 主设备ID,对应表busi_site_tree.id.
unsigned char s_eqm_code[DEF_EQM_CODE_SIZE]; // 主设备ID,对应表busi_site_tree.idmap.key
unsigned char s_sys_code[DEF_EQM_CODE_SIZE]; // 从设备ID,对应表busi_site_tree.idmap.key
unsigned char s_eqm_type; // 设备类型 1:主变 2:GIS 3:测温 4:避雷器
unsigned char wstate; // 主变+GIS,工作状态 1-发电状态 2抽水状态 3空闲状态
unsigned char bClose; // GIS的开合状态0:分 1:合
unsigned char bfault; // 主变事故状态0-正常 1-事故状态
}ST_DEV_RELATION;
// 主变id工作状态列表
typedef struct{
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 主设备ID,对应表busi_site_tree.id.
unsigned char eqm_name[DEF_BUFFER_128]; // 设备名称
unsigned char wstate; // 主变+GIS,工作状态 1-发电状态 2抽水状态 3空闲状态
unsigned char bfault; // 主变事故状态0-正常 1-事故状态
}ST_BYQWORK_STATUS;
// 是否有报警
//bool isWarnning(unsigned char *site_id, unsigned char *sys_code, int state, unsigned int saddr, double val);
bool isWarnning(ST_IECPOINT_TABLE &stPointt, double val);
// 获取系统设定的阈值
double getThresholdValuse(const char *eqm_code, const char *pFiledName, int jobState);
// 根据s_eqm_code获取对应的主变设备编码
bool bGetMasterEqmCodeBySubEqmCode(unsigned char *site_id, unsigned char *s_eqm_code, unsigned char *m_eqm_code);
// 刷新主变设备/GIS/避雷器运行状态
void flushDevWorkState(unsigned char *site_id, unsigned char *m_eqm_code, unsigned char state);
//刷新主变设备机组事故状态 state=false:正常 true:事故
bool flushFaultState(unsigned char *site_id, unsigned char *m_eqm_code, unsigned char state);
// 刷新GIS开关状态
bool flushDevCloseState(unsigned char *site_id, unsigned char *s_eqm_code, unsigned char state);
// 获取GIS的开关状态
unsigned char getGisOpenCloseState(unsigned char *site_id, unsigned char *s_eqm_code);
//从隶属关系map中获取设备工作状态
//返回0无效状态-没有找到该设备/设备无关联关系存在
unsigned char cGetCurrentWorkState(/*unsigned char *pszSite_id,*/ unsigned char *pszEqm_code);
/*************************************************************************/
// 设置主变工作状态
void vSetByqDeviceState(unsigned char *pszEqm_code, unsigned char state);
// 获取工作状态
unsigned char cGetByqDeviceState(unsigned char *pszEqm_code);
// 设置主变事故状态
void vSetByqDeviceFaultState(unsigned char *pszEqm_code, unsigned char state);
// 获取事故状态
unsigned char cGetByqDeviceFaultState(unsigned char *pszEqm_code);
void SethDevTimeStat(unsigned char *sys_code, unsigned char ws);
time_t GetDevTimeStat(unsigned char *sys_code, unsigned char *ws);
#pragma pack (pop)
#endif // end

@ -0,0 +1,42 @@
/****************************************************************************
** File name : HTMutex.cpp
** Description : define mutex type
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_MUTEX_H
#define __HT_MUTEX_H
#ifndef _WIN32 //for unix
#define mutex pthread_mutex_t
#define mutex_create(X) pthread_mutex_init(&X, NULL)
#define mutex_close(X) pthread_mutex_destroy(&X)
#define mutex_lock(X) pthread_mutex_lock(&X)
#define mutex_unlock(X) pthread_mutex_unlock(&X)
#else //for winX
#define mutex HANDLE
#define mutex_create(X) X = CreateMutex(NULL, FALSE, NULL)
#define mutex_close(X) CloseHandle(X)
#define mutex_lock(X) WaitForSingleObject(X, INFINITE)
#define mutex_unlock(X) ReleaseMutex(X)
#endif
// delay tims, millisecond(ms)
#ifndef _WIN32 //for unix
#define _SLEEP(X) usleep(X * 1000)
#else //for winX
#define _SLEEP(X) Sleep(X) //ms
#endif
#ifdef _WIN32 //for unix
#define snprintf _snprintf
#endif
#endif // end __HT_MUTEX_H

@ -0,0 +1,548 @@
/****************************************************************************
** File name : HTOpencvImg.h
** Description : define Opencv function
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_OPENCV_IMG_H
#define __HT_OPENCV_IMG_H
#pragma warning(disable: 4819)
#include <stdio.h>
#include "HTGlobal.h"
//#include "opencv/cv.h"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/ml.hpp"
#include "opencv2/objdetect.hpp"
//#define _HT_OPENCV_TEST_ENV // 测试环境,产生随机数作为分析表的数据
#pragma pack (push ,1)
//OpencvDirTraverse.cpp : Defines the entry point for the console application.
#ifdef _WIN32
#pragma comment(lib,"opencv_world300d.lib")
//#pragma comment(lib,"opencv_ts300d.lib")
#endif
using namespace std;
using namespace cv;
#if (defined _WIN32) || (defined _WIN64)
static const char HT_CONFIMG_FILE[] = "..\\etc\\htimg-win.conf";
#else
static const char HT_CONFIMG_FILE[] = "../etc/htimg.conf";
#endif
#define eps 0.0000000001
#define PI acos(-1.0)
//#define MAX_FILE_SIZE 8294454 // 图片文件大小(字节)
//#define MAX_FILE_SIZE 177400
//#define _IM_SHOW // 显示图片
//#define _IMG_MIDILL_SAVE // 保存最终变换图片
typedef struct _CONF_IMG {
//[CAMERA_01]
int seqno; // 序列号,001-999之间
unsigned char eqm_type[2]; // 主设备类型, T-主变 G-GIS B-避雷器
unsigned char site_id[DEF_EQM_CODE_SIZE]; // 站点ID
unsigned char eqm_code[DEF_EQM_CODE_SIZE]; // 主设备编码
unsigned char sys_code[DEF_EQM_CODE_SIZE]; // 主设备系统编码
unsigned char table_type[32]; // 仪表类型名称
unsigned char name[32]; //# 拍摄对象名称,变压器放电拍照设备
unsigned char sersorid[DEF_EQM_CODE_SIZE]; //# 设备的sersor_id, 与数据库一一对应
unsigned int base_angle; //# 仪表基准度数, 180° 或360°
unsigned char meter_type; //# 仪表的数据单位类型, 0:电流 1 : 压力 2 : 容量(油位) 3: 温度
unsigned char meter_units; //# 对应于meter_type的单位
unsigned char direct_Clockwise;// 仪表读数的方向, 正时针 = 1 反时针 = 0
double dInitVal; // 初始值
unsigned int max_pointer_len; //# 最大指针长度(mm), 20mm~200mm, 默认:100
unsigned char img_path[MAX_PATH]; // 图片文件路径及类型: ../img01/*.* or ../img01/*.jpg ...
unsigned char img_bak[MAX_PATH]; // 图片文件备份路径../img01/bak ...
bool is_replace; //true: 覆盖原文件,不保留原文件,文件名不变;false: 保留原文件,并将截图文件命名为 xxx_cut.xxx
//# 截图区域配置
int s_height; //# 起始行 / 高度 / Y / H / rows
int e_height; //# 结束行 / 高度 / Y / H / rows
int s_width; //# 起始列 / 宽度 / X / W / cols
int e_width; //# 结束列 / 宽度 / X / W / cols
int img_min_size; // 图片文件最小字节数
}ST_OPENCV_CONF;
typedef struct _YB_TYPE {
int len; // 线长度
double du; // 角度
double val; // 对应的值
}ST_YB_TYPE;
static const ST_YB_TYPE g_YB_3EX5050[] =
{
{ 156, 139.00, 0 },
{ 156, 127.00, 1 },
{ 156, 116.00, 2 },
{ 156, 105.00, 3 },
{ 156, 90.00, 10 },
{ 156, 75.00, 20 },
{ 156, 52.00, 30 },
{ -1, 0, 0 }
};
static const ST_YB_TYPE g_YB_JSY10[] =
{
{ 306, 90.00, 0 },
{ 306, 54.00, 1 },
{ 306, 18.00, 2 },
{ 306, 342.00, 3 },
{ 306, 306.00, 4 },
{ 306, 270.00, 5 },
{ 306, 234.00, 6 },
{ 306, 198.00, 7 },
{ 306, 162.00, 8 },
{ 306, 126.00, 9 },
{ -1, 0, 0 }
};
static const ST_YB_TYPE g_YB_YZFTH[] =
{
{ 220, 45.00, 10.00 },
{ 220, 47.70, 9.90 },
{ 220, 50.40, 9.80 },
{ 220, 53.10, 9.70 },
{ 220, 55.80, 9.60 },
{ 220, 58.50, 9.50 },
{ 220, 61.20, 9.40 },
{ 220, 63.90, 9.30 },
{ 220, 66.60, 9.20 },
{ 220, 69.30, 9.10 },
{ 220, 72.00, 9.00 },
{ 220, 74.70, 8.90 },
{ 220, 77.40, 8.80 },
{ 220, 80.10, 8.70 },
{ 220, 82.80, 8.60 },
{ 220, 85.50, 8.50 },
{ 220, 88.20, 8.40 },
{ 220, 90.90, 8.30 },
{ 220, 93.60, 8.20 },
{ 220, 96.30, 8.10 },
{ 220, 99.00, 8.00 },
{ 220, 101.70, 7.90 },
{ 220, 104.40, 7.80 },
{ 220, 107.10, 7.70 },
{ 220, 109.80, 7.60 },
{ 220, 112.50, 7.50 },
{ 220, 115.20, 7.40 },
{ 220, 117.90, 7.30 },
{ 220, 120.60, 7.20 },
{ 220, 123.30, 7.10 },
{ 220, 126.00, 7.00 },
{ 220, 128.70, 6.90 },
{ 220, 131.40, 6.80 },
{ 220, 134.10, 6.70 },
{ 220, 136.80, 6.60 },
{ 220, 139.50, 6.50 },
{ 220, 142.20, 6.40 },
{ 220, 144.90, 6.30 },
{ 220, 147.60, 6.20 },
{ 220, 150.30, 6.10 },
{ 220, 153.00, 6.00 },
{ 220, 155.70, 5.90 },
{ 220, 158.40, 5.80 },
{ 220, 161.10, 5.70 },
{ 220, 163.80, 5.60 },
{ 220, 166.50, 5.50 },
{ 220, 169.20, 5.40 },
{ 220, 171.90, 5.30 },
{ 220, 174.60, 5.20 },
{ 220, 177.30, 5.10 },
{ 220, 180.00, 5.00 },
{ 220, 182.70, 4.90 },
{ 220, 185.40, 4.80 },
{ 220, 188.10, 4.70 },
{ 220, 190.80, 4.60 },
{ 220, 193.50, 4.50 },
{ 220, 196.20, 4.40 },
{ 220, 198.90, 4.30 },
{ 220, 201.60, 4.20 },
{ 220, 204.30, 4.10 },
{ 220, 207.00, 4.00 },
{ 220, 209.70, 3.90 },
{ 220, 212.40, 3.80 },
{ 220, 215.10, 3.70 },
{ 220, 217.80, 3.60 },
{ 220, 220.50, 3.50 },
{ 220, 223.20, 3.40 },
{ 220, 225.90, 3.30 },
{ 220, 228.60, 3.20 },
{ 220, 231.30, 3.10 },
{ 220, 234.00, 3.00 },
{ 220, 236.70, 2.90 },
{ 220, 239.40, 2.80 },
{ 220, 242.10, 2.70 },
{ 220, 244.80, 2.60 },
{ 220, 247.50, 2.50 },
{ 220, 250.20, 2.40 },
{ 220, 252.90, 2.30 },
{ 220, 255.60, 2.20 },
{ 220, 258.30, 2.10 },
{ 220, 261.00, 2.00 },
{ 220, 263.70, 1.90 },
{ 220, 266.40, 1.80 },
{ 220, 269.10, 1.70 },
{ 220, 271.80, 1.60 },
{ 220, 274.50, 1.50 },
{ 220, 277.20, 1.40 },
{ 220, 279.90, 1.30 },
{ 220, 282.60, 1.20 },
{ 220, 285.30, 1.10 },
{ 220, 288.00, 1.00 },
{ 220, 290.70, 0.90 },
{ 220, 293.40, 0.80 },
{ 220, 296.10, 0.70 },
{ 220, 298.80, 0.60 },
{ 220, 301.50, 0.50 },
{ 220, 304.20, 0.40 },
{ 220, 306.90, 0.30 },
{ 220, 309.60, 0.20 },
{ 220, 312.30, 0.10 },
{ 220, 315.00, 0.00 },
{ -1, 0, 0 }
};
// 150摄氏度的油温表读数
static const ST_YB_TYPE g_YB_WSS150[] =
{
{ 183, 225.00, 0.00 },
{ 183, 219.60, 3.00 },
{ 183, 214.20, 6.00 },
{ 183, 208.80, 9.00 },
{ 183, 203.40, 12.00 },
{ 183, 198.00, 15.00 },
{ 183, 192.60, 18.00 },
{ 183, 187.20, 21.00 },
{ 183, 181.80, 24.00 },
{ 183, 176.40, 27.00 },
{ 183, 171.00, 30.00 },
{ 183, 165.60, 33.00 },
{ 183, 160.20, 36.00 },
{ 183, 154.80, 39.00 },
{ 183, 149.40, 42.00 },
{ 183, 144.00, 45.00 },
{ 183, 138.60, 48.00 },
{ 183, 133.20, 51.00 },
{ 183, 127.80, 54.00 },
{ 183, 122.40, 57.00 },
{ 183, 117.00, 60.00 },
{ 183, 111.60, 63.00 },
{ 183, 106.20, 66.00 },
{ 183, 100.80, 69.00 },
{ 183, 95.40, 72.00 },
{ 183, 90.00, 75.00 },
{ 183, 84.60, 78.00 },
{ 183, 79.20, 81.00 },
{ 183, 73.80, 84.00 },
{ 183, 68.40, 87.00 },
{ 183, 63.00, 90.00 },
{ 183, 57.60, 93.00 },
{ 183, 52.20, 96.00 },
{ 183, 46.80, 99.00 },
{ 183, 41.40, 102.00 },
{ 183, 36.00, 105.00 },
{ 183, 30.60, 108.00 },
{ 183, 25.20, 111.00 },
{ 183, 19.80, 114.00 },
{ 183, 14.40, 117.00 },
{ 183, 9.00, 120.00 },
{ 183, 3.60, 123.00 },
{ 183, 358.20, 126.00 },
{ 183, 325.80, 129.00 },
{ 183, 347.40, 132.00 },
{ 183, 342.00, 135.00 },
{ 183, 336.60, 138.00 },
{ 183, 331.20, 141.00 },
{ 183, 325.80, 144.00 },
{ 183, 320.40, 147.00 },
{ 183, 315.00, 150.00 },
{ -1, 0, 0 }
};
// 100摄氏度的温度表读数
static const ST_YB_TYPE g_YB_WSS100[] =
{
{ 183, 225.00, 0.00 },
{ 183, 219.60, 2.00 },
{ 183, 214.20, 4.00 },
{ 183, 208.80, 6.00 },
{ 183, 203.40, 8.00 },
{ 183, 198.00, 10.00 },
{ 183, 192.60, 12.00 },
{ 183, 187.20, 14.00 },
{ 183, 181.80, 16.00 },
{ 183, 176.40, 18.00 },
{ 183, 171.00, 20.00 },
{ 183, 165.60, 22.00 },
{ 183, 160.20, 24.00 },
{ 183, 154.80, 26.00 },
{ 183, 149.40, 28.00 },
{ 183, 144.00, 30.00 },
{ 183, 138.60, 32.00 },
{ 183, 133.20, 34.00 },
{ 183, 127.80, 36.00 },
{ 183, 122.40, 38.00 },
{ 183, 117.00, 40.00 },
{ 183, 111.60, 42.00 },
{ 183, 106.20, 44.00 },
{ 183, 100.80, 46.00 },
{ 183, 95.40, 48.00 },
{ 183, 90.00, 50.00 },
{ 183, 84.60, 52.00 },
{ 183, 79.20, 54.00 },
{ 183, 73.80, 56.00 },
{ 183, 68.40, 58.00 },
{ 183, 63.00, 60.00 },
{ 183, 57.60, 62.00 },
{ 183, 52.20, 64.00 },
{ 183, 46.80, 66.00 },
{ 183, 41.40, 68.00 },
{ 183, 36.00, 70.00 },
{ 183, 30.60, 72.00 },
{ 183, 25.20, 74.00 },
{ 183, 19.80, 76.00 },
{ 183, 14.40, 78.00 },
{ 183, 9.00, 80.00 },
{ 183, 3.60, 82.00 },
{ 183, 361.80, 84.00 },
{ 183, 356.40, 86.00 },
{ 183, 351.00, 88.00 },
{ 183, 345.60, 90.00 },
{ 183, 340.20, 92.00 },
{ 183, 334.80, 94.00 },
{ 183, 329.40, 96.00 },
{ 183, 324.00, 98.00 },
{ 180, 318.60, 100.00 },
{ -1, 0, 0 }
};
// 1.6MPa压力表读数
static const ST_YB_TYPE g_YB_OCR17NI12MO2_16[] =
{
{ 183, 225.00, 0.00 },
{ 183, 221.63, 0.02 },
{ 183, 218.25, 0.04 },
{ 183, 214.88, 0.06 },
{ 183, 211.50, 0.08 },
{ 183, 208.13, 0.10 },
{ 183, 204.75, 0.12 },
{ 183, 201.38, 0.14 },
{ 183, 198.00, 0.16 },
{ 183, 194.63, 0.18 },
{ 183, 191.25, 0.20 },
{ 183, 187.88, 0.22 },
{ 183, 184.50, 0.24 },
{ 183, 181.13, 0.26 },
{ 183, 177.75, 0.28 },
{ 183, 174.38, 0.30 },
{ 183, 171.00, 0.32 },
{ 183, 167.63, 0.34 },
{ 183, 164.25, 0.36 },
{ 183, 160.88, 0.38 },
{ 183, 157.50, 0.40 },
{ 183, 154.13, 0.42 },
{ 183, 150.75, 0.44 },
{ 183, 147.38, 0.46 },
{ 183, 144.00, 0.48 }, // 144.74 - 0.5
{ 183, 140.63, 0.50 },
{ 183, 137.25, 0.52 },
{ 183, 133.88, 0.54 },
{ 183, 130.50, 0.56 },
{ 183, 127.13, 0.58 },
{ 183, 123.75, 0.60 },
{ 183, 120.38, 0.62 },
{ 183, 117.00, 0.64 },
{ 183, 113.63, 0.66 },
{ 183, 110.25, 0.68 },
{ 183, 106.88, 0.70 },
{ 183, 103.50, 0.72 },
{ 183, 100.13, 0.74 },
{ 183, 96.75, 0.76 },
{ 183, 93.38, 0.78 },
{ 183, 90.00, 0.80 },
{ 183, 86.63, 0.82 },
{ 183, 83.25, 0.84 },
{ 183, 79.88, 0.86 },
{ 183, 76.50, 0.88 },
{ 183, 73.13, 0.90 },
{ 183, 69.75, 0.92 },
{ 183, 66.38, 0.94 },
{ 183, 63.00, 0.96 },
{ 183, 59.63, 0.98 },
{ 183, 56.25, 1.00 },
{ 183, 52.88, 1.02 },
{ 183, 49.50, 1.04 },
{ 183, 46.13, 1.06 },
{ 183, 42.75, 1.08 },
{ 183, 39.38, 1.10 },
{ 183, 36.00, 1.12 },
{ 183, 32.63, 1.14 },
{ 183, 29.25, 1.16 },
{ 183, 25.88, 1.18 },
{ 183, 22.50, 1.20 },
{ 183, 19.13, 1.22 },
{ 183, 15.75, 1.24 },
{ 183, 12.38, 1.26 },
{ 183, 9.00, 1.28 },
{ 183, 5.63, 1.30 },
{ 183, 2.25, 1.32 },
{ 183, 361.13, 1.34 },
{ 183, 357.75, 1.36 },
{ 183, 354.38, 1.38 },
{ 183, 351.00, 1.40 },
{ 183, 347.63, 1.42 },
{ 183, 344.25, 1.44 },
{ 183, 340.88, 1.46 },
{ 183, 337.50, 1.48 },
{ 183, 334.13, 1.50 },
{ 183, 330.75, 1.52 },
{ 183, 327.38, 1.54 },
{ 183, 324.00, 1.56 },
{ 183, 320.63, 1.58 },
{ 180, 317.25, 1.60 },
{ -1, 0, 0 }
};
// 2.5MPa压力表读数
static const ST_YB_TYPE g_YB_OCR17NI12MO2_25[] =
{
{ 183, 225.00, 0.00 },
{ 183, 219.60, 0.05 },
{ 183, 214.20, 0.10 },
{ 183, 208.80, 0.15 },
{ 183, 203.40, 0.20 },
{ 183, 198.00, 0.25 },
{ 183, 192.60, 0.30 },
{ 183, 187.20, 0.35 },
{ 183, 181.80, 0.40 },
{ 183, 176.40, 0.45 },
{ 183, 171.00, 0.50 },
{ 183, 165.60, 0.55 },
{ 183, 160.20, 0.60 },
{ 183, 154.80, 0.65 },
{ 183, 149.40, 0.70 },
{ 183, 144.00, 0.75 },
{ 183, 138.60, 0.80 },
{ 183, 133.20, 0.85 },
{ 183, 127.80, 0.90 },
{ 183, 122.40, 0.95 },
{ 183, 117.00, 1.00 },
{ 183, 111.60, 1.05 },
{ 183, 106.20, 1.10 },
{ 183, 100.80, 1.15 },
{ 183, 95.40, 1.20 },
{ 183, 90.00, 1.25 },
{ 183, 84.60, 1.30 },
{ 183, 79.20, 1.35 },
{ 183, 73.80, 1.40 },
{ 183, 68.40, 1.45 },
{ 183, 63.00, 1.50 },
{ 183, 57.60, 1.55 },
{ 183, 52.20, 1.60 },
{ 183, 46.80, 1.65 },
{ 183, 41.40, 1.70 },
{ 183, 36.00, 1.75 },
{ 183, 30.60, 1.80 },
{ 183, 25.20, 1.85 },
{ 183, 19.80, 1.90 },
{ 183, 14.40, 1.95 },
{ 183, 9.00, 2.00 },
{ 183, 3.60, 2.05 },
{ 183, 361.80, 2.10 },
{ 183, 356.40, 2.15 },
{ 183, 351.00, 2.20 },
{ 183, 345.60, 2.25 },
{ 183, 340.20, 2.30 },
{ 183, 334.80, 2.35 },
{ 183, 329.40, 2.40 },
{ 183, 324.00, 2.45 },
{ 183, 318.60, 2.50 },
{ -1, 0, 0 }
};
#pragma pack (pop)
//181 - 0 = 181
//530 -
//495
//224
//135
//123
//92
//自定义直线
class MyLine
{
public:
int id; //编号
int k; //倾斜角[0-360)
int l; //长度
public:
MyLine(int ID = 0, int K = 0, int L = 0){ id = ID, k = K, l = L; } //构造函数
bool operator<(const MyLine &A) { return k < A.k; } //重定义小于号
void print(){ printf("id: %3d k: %3d° l: %3d\n", id, k, l); }//输出函数
};
//显示图片
void showImg(const char *title, Mat &img);
//点到线段的距离
double DistancetoSegment(Point P, Point A, Point B);
//向量模长
double Length(Point A);
double gtest(double du, double base, int linelen); // for test
// 读取仪表指针数值
//double dReadPointValue(const char *tbale_type, const char *jpg_file, double base);
double dReadPointValue_JSY10(ST_OPENCV_CONF *stConf, const char *jpg_file);
double dReadPointValue_3EX5050(ST_OPENCV_CONF *stConf, const char *jpg_file);
//double dReadPointValue_YZF250TH_T4(ST_OPENCV_CONF *stConf, const char *jpg_file);
double dReadPointValues(ST_OPENCV_CONF *stConf, const char *jpg_file);
//double dGetReadValueOfYZFTH(double du, double base, int linelen);
/*
pPath : path, eg: /usr/local/img/*.jpg
: "D:\\Photo and Video\\destop1\\*.jpg";
*/
int iGetImgFileList(const char *pPath, std::vector<cv::String> & image_files);
// 播放视频流
int showRtspVideoStream(const char* rtsp_url);
int showRtspVideoStreams(const char *rtsp_url);
// 截取图片指定区域并保存
// isReplace = true: 覆盖原文件,不保留原文件,文件名不变
// = false: 保留原文件,并将截图文件命名为 xxx_cut.xxx
//int vCutImageSave(char* path_filename, int shigh, int ehigh, int swidth, int ewidth, bool isReplace);
int vCutImageSave(ST_OPENCV_CONF *stConf, char* path_filename);
// 仪表盘的单位转换
double dChangeUnits(unsigned char *sersorid, double inVal);
// 图片识别处理线程
void* thread_opencv_proc(void * arg);
bool bBakFilename(char *filename, char *pBakPath);
double dReadPointValue_Wss411_150_T1(ST_OPENCV_CONF *stConf, const char *jpg_file);
#endif // !__HT_OPENCV_IMG_H_

@ -0,0 +1,226 @@
/****************************************************************************
** File name : HTPublic.h
** Description : define common api
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_PUBLIC_H
#define __HT_PUBLIC_H
#ifdef _WIN32
#pragma comment(lib,"ws2_32.lib")
#endif
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <time.h> /* timespec{} for pselect() */
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <fcntl.h> /* for nonblocking */
#include <stdarg.h>
#include <assert.h>
#include "HTType.h"
using namespace std;
#ifdef _WIN32
#include <direct.h>
#include <io.h>
#include <process.h>
#include <winsock2.h>
#include <objbase.h>
#include <guiddef.h>
#else
#include <sys/io.h>
#include <sys/socket.h>
#include <linux/unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <netdb.h>
#include <inttypes.h>
#include <sys/time.h>
#include <pthread.h>
#include <strings.h>
#include <dirent.h>
#include <asm/unistd.h>
#include <sys/wait.h>
#include <uuid/uuid.h>
#endif
/*
#if defined(__linux__) && defined(__NR_gettid)
#define GETTID() syscall(__NR_gettid)
#else
#define GETTID() getpid()
#endif
*/
#ifdef _WIN32
#define GETTID() GetCurrentThreadId() // 获取线程ID
#define GETPID() GetCurrentProcessId() // 获取主进程ID
#else
#define GETTID() syscall(__NR_gettid)
#define GETPID() getpid() // 获取主进程ID
#endif
#define DEF_PID_FILE "../run/pid_file.pid" // 程序主进程ID文件
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void vSetPid();
int iGetPid();
// 时间函数
void vGetHostTime (char *pszTime) ;
time_t vGetHostTimeFmt (char *pszTime) ;
time_t vGetHostTimeFmtBeforBay(char *pszTime, int beforbay);
void vTranHostTimeFmt (time_t t, char *pszTime);
time_t strTime2int(char *pszTime);
time_t strTimeFmt2int(char *pszTime);
void getCurrentBefor360Hour(char *pstime, char *petime);
time_t vGeOneDayTimeFmt(char *pSTime, char *pETime);
void vFormatTimes(char *pszInTimeStr, char *pszOutFormatTime);
time_t getUTCLongTime (void) ;
void getUTCFmtTime (char *pszTime) ;
void UTC2FmtTime (time_t utc, char *pszTime) ;
void UTC2LocalTime (time_t utc, char *pszTime) ;
void diffTimes(unsigned int c, char *pszTime);
unsigned int uiTime (void) ;
int getCurrTimeDiff(unsigned char *bcd_t) ;
time_t local2Utc(unsigned char *pTime, int iLen);
time_t local2UtcTime(time_t localTime);
int getuuid(char *str, int inlen);
void vGetHostTimeOnMillsecond(char *pszTime); // 获取时间,YYYYMMDDHH24MISS:MLSS
time_t vGetHostTimeFmtOnMillsecond(char *pszTime); // 获取时间,YYYY-MM-DD HH24:MI:SS+MLSS
unsigned int getWarnID(unsigned char *pTime, int iLen, unsigned int id);
// 目录操作函数
int iDirOrFileExist(const char *pszName);
int iBuildDirent(const char *pName);
int iSplitNumberFiled(char *pstr, char node, int no);
int iSplitStringFiled(char *pstr, char node, char no, char *pFiled);
int get_file_size(const char *path);
int getFileCreateTime(const char *path, char *pCreateTime);
bool bSplitFilenameByFullPath(char *pFullPath, char *pPrantPath, char *pFilename, char *pExt);
// 将Linux文件路径转为Windows的路径格式
void Unix2WindowPath(char *pszPath);
void Window2UnixPath(char *pszPath);
void getGnssData(unsigned char *p_date);
void getGnssTime(unsigned char *p_time);
void setPostionDate(unsigned char *pDate, unsigned char *pTime);
void setPostionTime(unsigned char *pDate, unsigned char *pTime);
int iTrimVersionHeadChar(char *strver);
void LRTrim(unsigned char *str);
int RigthTrim(unsigned char *str);
int LeftTrim(unsigned char *str);
void MiddleTrim(unsigned char *str);
bool isStringDigit(char *pstr);
int stringcasecmp(const char *ps1, const char *ps2);
int stringncasecmp(const char *ps1, const char *ps2, int length);
int bits_check(unsigned char *map, int field_no);
void getDateFromTime(char* p_time,char* p_date);
void getTimeFromTime(char* p_time,char* p_times);
void bcd_to_asc(unsigned char *pusFrom, unsigned int uiFromLen,unsigned char *pusTo);
void asc_to_bcd(unsigned char *pusFrom, unsigned int uiFromLen, unsigned char *pusTo);
unsigned int htoni(unsigned int us);
unsigned int ntohi(unsigned int us);
double getRandByTime();
#ifdef ntohll
utint64 ntohll(utint64 arg64) ;
#endif
#ifdef htonll
utint64 htonll(utint64 arg64) ;
#endif
unsigned int int64To32(utint64 u64);
void LocalTime2Bcd(char *pLocalTime, char *pBcd);
int getStringLen(unsigned char *pstr, int length);
int getHexString(unsigned char *str, int length, unsigned char *pstr);
/*************************************************************************
Function : 32
Param in :
num : source uint
Param out :
pBin : object strings.(min length = 32)
Return Code : none
*************************************************************************/
void uint32_binstr(unsigned int num, char* pBin);
/*************************************************************************
Function : 64
Param in :
num : source uint
Param out :
pBin : object strings.(min length = 64)
Return Code : none
*************************************************************************/
void uint64_binstr(utint64 num, char* pBin);
/*************************************************************************
Function : 32
Param in :
pBin : source bin string(eg. 1010101001111), need '\0' end.
Param out :
: none
Return Code : uint32 interger
*************************************************************************/
unsigned int binstr_uint32(char *pBin);
/*************************************************************************
Function : 64
Param in :
pBin : source bin string(eg. 1010101001111), need '\0' end.
Param out :
: none
Return Code : utint64 interger
*************************************************************************/
utint64 binstr_uint64(char *pBin);
/*************************************************************************
Function :
Param in :
str : source string(eg. 1010101001111), need '\0' end.
len : source length
Param out :
: str
Return Code : str, null is faild
*************************************************************************/
char* strSwap(char* szT,int len);
#ifdef __cplusplus
}
#endif
#endif // end __HT_PUBLIC_H

@ -0,0 +1,97 @@
/****************************************************************************
** File name : HTTcpSocket.h
** Description : define common api for tcp socket
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_TCP_SOCKET_H
#define __HT_TCP_SOCKET_H
#include "HTPublic.h"
//#include <mstcpip.h>
static const int MAX_SEND_INFO = 512; //最大发送包长度
static const int MAX_SBUFF_TCP = 2048; //发送最大包长度
// static const int MAX_DATA_INFO = 1024; //数据包做大长度
#ifdef _WIN32
#ifndef ECONNRESET
#define ECONNRESET WSAECONNRESET //errno= 104 = Connection reset by peer
#endif
#endif
#ifndef INVALID_HANDLE
#define INVALID_HANDLE -1 // 无效句柄
#endif
/* socket listen number */
#define LISTENQ 20
#define MAX_TEMP_BUFFER_SIZE 2048
/* error code define */
#define ErrOpenServer -1000 /* Open Server Fail */
#define ErrSockParam -1001 /* Socket Param error */
#define ErrSendFail -1002 /* send data fail or socket exception*/
#define ErrRecvTimeOut -1003 /* recv data time out */
#define ErrRecvFail -1004 /* recv data fail */
#define ErrOpenFile -1005 /* open dest file fail */
#define ErrSetSockOpt -1006 /* set socket options */
#define ErrBindFail -1007 /* set socket bind fail*/
#define ErrGetPeerIP -1008 /* Get PeerIP Fail */
#define ErrListenFail -1009 /* socket listen error */
#define ErrTimeStrFmt -1020 /* Input time string error */
#define ErrEintr -1021 /* Interrupted system call,EINTR*/
#define ErrException -1022 /* socket exceptions close */
class TTcpSocket
{
public:
void clear_tcp_buffer(int socket_fd, int nbytes);
bool tcpIsConnected(int sockid);
// 根据sockid获取源地址和源端口
int getPeerInfo(int sockid, unsigned char *sip, unsigned short *sport);
int getLocalSocketInfo(int sockid, unsigned char *sip, unsigned short *sport);
int tcpRecvBuffer(int sockid, char* pBuffer,int nMaxLength, int timeout=6);
int tcpSendBuffer(int sockid, const char *pBuffer, int length);
int tcpAcceptSocket(int sockid);
int tcpCloseSocket(int sockfd);
int tcpOpenServer(const char *ip,unsigned short port);
int tcpSetlinger(int sockid);
int tcpSetNodelay(int sockid) ;
int tcpConnect(const char *pszIP, short port, int iTimeout);
void tcpSetServerfd(int fd);
void tcpSetSockID(int fd);
int tcpGetServerfd();
int tcpGetSockID();
TTcpSocket();
virtual ~TTcpSocket();
//长连接测试函数
//bool tcpClient_Keep() ;
private:
#ifndef _WIN32
void SetSocketMode(int sockid,int iMode=O_NONBLOCK) ; //O_NONBLOCK=04000
#else
void SetSocketMode(int sockid,int iMode=04000) ; //O_NONBLOCK=04000
#endif
private:
unsigned short m_tcpPort;
bool m_tcpConnected;
int m_sockid;
int m_server_fd;
};
#endif // end __HT_TCP_SOCKET_H

@ -0,0 +1,67 @@
/****************************************************************************
** File name : HTTestOpencv.h
** Description : define Opencv Test function
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_TESTOPENCV__H
#define __HT_TESTOPENCV__H
#pragma warning(disable: 4819)
#include "HTGlobal.h"
#include "opencv2/opencv.hpp"
#include "opencv/cv.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#pragma pack (push ,1)
//OpencvDirTraverse.cpp : Defines the entry point for the console application.
#ifdef _WIN32
#pragma comment(lib,"opencv_world300d.lib")
#endif
using namespace std;
using namespace cv;
#pragma pack (pop)
int HTCanny(char *filename);
// 图片矫正
void ImageRecify(const char* pInFileName);
void ImgRotate(const char *img_file);
void SendMessageOne(char *rtsp_url);
// 鼠标选取区域,实现截图功能并保持图片
void vCutPicture(char *filename);
// 检测矩形
int iCheckFangXiang(char *filename);
//检测圆方法
int iCheckCircles(char *filename);
//检测直线方法
int iCheckLine(char *filename);
void CannyThreshold(int, void*);
void vHoughLines(int, void*);
void HTImgAnalys(const char *img_file);
void vInitPress_OCR17NI12MO2_16();
#endif // !__HT_OPENCV_IMG_H_

@ -0,0 +1,44 @@
/****************************************************************************
** File name : HTThread.h
** Description : define service threads
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_THREAD_H
#define __HT_THREAD_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// 线程接口定义
int HTInitThreadHandle(void);
void HTFreeThreadHandle(void);
void pthread_testcancels(void);
int ht_pthread_create_background(pthread_t *thread_handle, void *(*pfunc)(void *), void *data);
// void *thread_parser_proc(void * arg);
// void *thread_opration_proc(void *arg) ;
// void *thread_respone_proc(void *arg) ;
//
// void *thread_client_proc(void * arg);
// void *thread_active_proc(void *arg) ;
#ifdef __cplusplus
}
#endif
#endif // end __HT_THREAD_H

@ -0,0 +1,69 @@
/****************************************************************************
** File name : HTType.h
** Description : define data type
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_TYPE_H
#define __HT_TYPE_H
#ifdef _WIN32
#ifndef int64
typedef __int64 tint64;
#endif
#else
#ifndef int64
typedef long long tint64 ;
#endif
#endif
#ifdef _WIN32
#ifndef utint64
typedef unsigned __int64 utint64;
#endif
#else
#ifndef utint64
typedef unsigned long long utint64 ;
#endif
#endif
#ifndef uint
typedef unsigned int uint;
#endif
#ifndef ulong
typedef unsigned long ulong;
#endif
#ifndef byte
typedef unsigned char byte;
#endif
#ifndef uchar
typedef unsigned char uchar;
#endif
#ifndef ushort
typedef unsigned short ushort;
#endif
#ifdef _WIN32
#ifndef pthread_t
typedef unsigned long pthread_t;
#endif
/*#else // Linux
#ifndef pthread_t
typedef pthread_t pthread_t; // bits/pthreadtypes.h typedef unsigned long int pthread_t;
#endif
*/
#endif
#endif // end __HT_TYPE_H

@ -0,0 +1,24 @@
/****************************************************************************
** File name : HTUnit.h
** Description : define const
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_UNIT_H
#define __HT_UNIT_H
// 计量单位转换
double getChangeUnit(short Unit, short sysUnit, double val);
bool bCompare(double ov, double nv, double rate);
#endif // end __HT_UNIT_H

@ -0,0 +1,19 @@
/****************************************************************************
** File name : HTVersion.h
** Description : define mutex type
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#ifndef __HT_VERSION_H
#define __HT_VERSION_H
#define HT_VERSION_BUILD_ID "20200526"
#endif // end __HT_VERSION_H

@ -0,0 +1,179 @@
#ifndef __HX_IEC104_H
#define __HX_IEC104_H
#include <stdio.h>
#include <stdlib.h>
#include "HTGlobal.h"
#define NS_IEC_104_YK_BASE_PORT 16
#define NS_IEC104_YK_PERMIT_TIME 16
#define NS_IEC_104_TOTAL_YX_TIMES 9
#define NS_IEC_104_ONCE_YX 120
#define NS_IEC_104_ONCE_YX_BYTES 120/8
#define NS_IEC_104_TOTAL_YC_TIMES 16
#define NS_IEC_104_ONCE_YC 32
#define NS_IEC_104_TOTAL_YM_TIMES 8
#define NS_IEC_104_ONCE_YM 16
#define NS_IEC_104_MIN_LENGTH 6
#define NS_IEC_104_HEAD 0x68
#define NS_IEC_104_STARTDT 0x04
#define NS_IEC_104_STOPDT 0x10
#define NS_IEC_104_TESTFR 0x40
#define NS_IEC_104_QCC_POSITION 15
#define NS_IEC_104_TIME_POSITION 15
#define NS_IEC_104_REASONBYTE 2
#define NS_IEC_104_ASDUADDRESSBYTE 2
#define NS_IEC_104_INFORMATIONBYTE 3
/* Location Which Bytes In Receive Buffer */
#define NS_STARTREASON 8
#define NS_STARTASDUADDRESS 10
#define NS_STARTINFORMATION 12
#define NS_STARTQUALIFIER 15
#define NS_IEC_104_GROUP_BYTE 15
#define NS_IEC104_GROUP_BEGIN 21
#define NS_IEC104_GROUP_END 36
#define NS_IEC104_YX_START_OBJECT 0x01
#define NS_IEC104_YC_START_OBJECT 0x701
#define NS_IEC104_YCYX_OBJECT_INDEX 0x80
#define NS_IEC104_SENDBUFFER 256
#define NS_IEC104_RECEIVEBUFFER 128
#define NS_CONNECTED 0x02
#define NS_DISCONNECTED 0x20
#define NS_IEC104_PERMIT_TIME 30
#define NS_IEC104_MAX_K 12
#define NS_IEC104_MAX_W 8
#define NS_IEC104_MAX_GROUP 30
#define NS_IEC104_MAX_YC 512
#define NS_IEC104_CHANGE_YC_CYCLE 16
#define NS_IEC104_ONCE_YC_COUNT 32
#define OFF false
typedef struct NS_IEC_104_NS_
{
struct sockaddr_in ServerAddress;
int NsNewSocketId;
unsigned char LinkState;
unsigned long LinkValidTime;
unsigned char Card;
short Port;
unsigned char ReceiveBuffer[NS_IEC104_RECEIVEBUFFER];
unsigned char SendBuffer[NS_IEC104_SENDBUFFER];
short SendLength;
short ReceiveLength;
unsigned short ReceiveIndex;
short ReceiveIndexLength;
unsigned char ApciCode;
unsigned char TransmitReason[2];
unsigned char CommonAsduAddress[2];
unsigned char InformationObject[4];
unsigned char FormatType;
unsigned char UCommand;
unsigned char ReceiveHimNumber[2];
unsigned short SendMeNumber;
unsigned short ApduLength;
unsigned char AsduType;
unsigned char AsduQualifier;
unsigned char Qcc;
unsigned char FreezeSign;
unsigned char PulseGroup;
unsigned char TimeSave[8];
unsigned char Table;
unsigned short HasSendNumber;
unsigned short NeedSendNumber;
unsigned short LeftSendNumber;
unsigned short K;
unsigned short W;
unsigned short ReceiveYkId;
unsigned char YkCellAction;
unsigned short YkCellNumber;
unsigned short YkKgNumber;
unsigned char YkNowState;
unsigned short MediaNumber;
unsigned char YkError;
unsigned char YkYtType;
unsigned char YkStartSign;
unsigned long YkStartTime;
unsigned short SystemState;
unsigned char DataBuff[160];
unsigned char SetTimeFlag;
unsigned char GroupSendBuffer[NS_IEC104_MAX_GROUP][NS_IEC104_SENDBUFFER];
unsigned short GroupSendLength[NS_IEC104_MAX_GROUP];
short YcLastValue[NS_IEC104_MAX_YC];
unsigned char YcNap[NS_IEC104_MAX_YC];
unsigned char YcChangeCycle;
unsigned short YcLibIndex;
unsigned short YcChangeCount;
unsigned char CosSign;
unsigned char NetRunSign;
unsigned char SetNetSign;
unsigned char TableNo;
/*unsigned short XYxNum;
unsigned short XYmNum;*/
unsigned short XYcNum;
unsigned short XYcCycleNum;
} NS_IEC104_MAIN;
#define NS_IEC104_USE_CYCLE 5
typedef struct _CYCLE
{
time_t LastTime;
time_t TimeNap ;
time_t TimeSign;
}NS_SEND_TIME_NAP;
typedef struct _SYS_DATE
{
unsigned short NsYxTableNumber;
unsigned short NsYmTableNumber;
unsigned short NsYcTableNumber;
}NS_SYSTEM_DATA_MODE ;
NS_IEC104_MAIN NsIec104Struct;
static NS_SEND_TIME_NAP NsIec104Cycle[NS_IEC104_USE_CYCLE];
static unsigned short NsIec104Nap[NS_IEC104_USE_CYCLE]={/*5*/120,15,20,25,30};
#endif

@ -0,0 +1,137 @@
/****************************************************************************
** File name : CP56Time.cpp
** Description : CP56Time IEC 60870-5-104 time data type implementation
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
static const char *_FILE_ ="HTCP56Time.cpp";
// Constructor: decode CP56Time data
CP56Time::CP56Time(unsigned char *data)
{
CP56TimeToTime(data, &stime);
}
CP56Time::~CP56Time(void)
{
}
//
// return time string of CP56Time decoded
//
void CP56Time::GetTimeString(char *buf, size_t size)
{
sprintf(buf,"%2.2d-%2.2d-%4.4d %2.2d:%2.2d:%2.2d.%3.3d", stime.wDay,
stime.wMonth, stime.wYear, stime.wHour, stime.wMinute,
stime.wSecond, stime.wMilliseconds);
return;
}
//
// return SYSTEMTIME structure of CP56Time decoded
//
SYSTEMTIME CP56Time::_GetSystemTime(void)
{
return stime;
}
//
// return FILETIME structure of CP56Time decoded
//
FILETIME CP56Time::_GetFileTime(void)
{
FILETIME ft = {0};
//SystemTimeToFileTime(&stime, &ft);
return ft;
}
//
// return CP56Time data of actual time.
//
void CP56Time::ActualTimeToCP56Time(unsigned char *data)
{
SYSTEMTIME st;
//GetSystemTime(&st);
TimeToCP56Time(&st, data);
}
//
// convert FILETIME to CP56Time
//
void CP56Time::TimeToCP56Time(FILETIME *ft, unsigned char *data)
{
SYSTEMTIME st;
//FileTimeToSystemTime(ft, &st);
TimeToCP56Time(&st, data);
}
//
// convert SYSTEMTIME to CP56Time
//
void CP56Time::TimeToCP56Time(SYSTEMTIME *st, unsigned char *data)
{
unsigned int m;
m = st->wMilliseconds + 1000 * st->wSecond;
data[0] = m & 0xFF;
data[1] = (m & 0xFF00)>>8;
data[2] = st->wMinute & 0x00FF; // add valid flag and genuine flag
data[3] = st->wHour & 0x00FF; // add summer flag
data[4] = ((st->wDayOfWeek%7)&0x03)<<5 | (st->wDay&0x1F);
data[5] = st->wMonth & 0x0F;
data[6] = st->wYear - 2000;
}
//
// convert CP56Time to FILETIME
//
void CP56Time::CP56TimeToTime(unsigned char *data, FILETIME *ft)
{
SYSTEMTIME st;
CP56TimeToTime(data, &st);
//SystemTimeToFileTime(&st, ft);
}
//
// convert CP56Time to SYSTEMTIME
//
void CP56Time::CP56TimeToTime(unsigned char *data, SYSTEMTIME *st)
{
unsigned int mili = data[0] | data[1]<<8;
st->wSecond = mili / 1000;
st->wMilliseconds = mili - st->wSecond*1000;
if(data[2] & 0x40)
genuine = true;
else
genuine = false;
if(data[2] & 0x80)
valid = true;
else
valid = false;
st->wMinute = data[2] & 0x3F;
st->wHour = data[3] & 0x1F;
if(data[3] & 0x80)
summer = true;
else
summer = false;
st->wDay = data[4] & 0x1F;
st->wDayOfWeek = (data[4] & 0xE0 ) >> 5;
if(st->wDayOfWeek) // if zero day of week not used.
st->wDayOfWeek = (st->wDayOfWeek + 1)%7;
st->wMonth = data[5] & 0x0F;
st->wYear = 2000 + (data[6] & 0x7F);
}

@ -0,0 +1,137 @@
/****************************************************************************
** File name : CP56Time2a.cpp
** Description : CP56Time2a IEC 60870-5-104 time data type implementation
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
static const char *_FILE_ ="HTCP56Time2a.cpp";
// Constructor: decode CP56Time2a data
CP56Time2a::CP56Time2a(unsigned char *data)
{
CP56Time2aToTime(data, &stime);
}
CP56Time2a::~CP56Time2a(void)
{
}
//
// return time string of CP56Time2a decoded
//
void CP56Time2a::GetTimeString(char *buf, size_t size)
{
sprintf(buf,"%2.2d-%2.2d-%4.4d %2.2d:%2.2d:%2.2d.%3.3d", stime.wDay,
stime.wMonth, stime.wYear, stime.wHour, stime.wMinute,
stime.wSecond, stime.wMilliseconds);
return;
}
//
// return SYSTEMTIME structure of CP56Time2a decoded
//
SYSTEMTIME CP56Time2a::_GetSystemTime(void)
{
return stime;
}
//
// return FILETIME structure of CP56Time2a decoded
//
FILETIME CP56Time2a::_GetFileTime(void)
{
FILETIME ft = {0};
//SystemTimeToFileTime(&stime, &ft);
return ft;
}
//
// return CP56Time2a data of actual time.
//
void CP56Time2a::ActualTimeToCP56Time(unsigned char *data)
{
SYSTEMTIME st;
//GetSystemTime(&st);
TimeToCP56Time2a(&st, data);
}
//
// convert FILETIME to CP56Time2a
//
void CP56Time2a::TimeToCP56Time2a(FILETIME *ft, unsigned char *data)
{
SYSTEMTIME st;
//FileTimeToSystemTime(ft, &st);
TimeToCP56Time2a(&st, data);
}
//
// convert SYSTEMTIME to CP56Time2a
//
void CP56Time2a::TimeToCP56Time2a(SYSTEMTIME *st, unsigned char *data)
{
unsigned int m;
m = st->wMilliseconds + 1000 * st->wSecond;
data[0] = m & 0xFF;
data[1] = (m & 0xFF00)>>8;
data[2] = st->wMinute & 0x00FF; // add valid flag and genuine flag
data[3] = st->wHour & 0x00FF; // add summer flag
data[4] = ((st->wDayOfWeek%7)&0x03)<<5 | (st->wDay&0x1F);
data[5] = st->wMonth & 0x0F;
data[6] = st->wYear - 2000;
}
//
// convert CP56Time2a to FILETIME
//
void CP56Time2a::CP56Time2aToTime(unsigned char *data, FILETIME *ft)
{
SYSTEMTIME st;
CP56Time2aToTime(data, &st);
//SystemTimeToFileTime(&st, ft);
}
//
// convert CP56Time2a to SYSTEMTIME
//
void CP56Time2a::CP56Time2aToTime(unsigned char *data, SYSTEMTIME *st)
{
unsigned int mili = data[0] | data[1]<<8;
st->wSecond = mili / 1000;
st->wMilliseconds = mili - st->wSecond*1000;
if(data[2] & 0x40)
genuine = true;
else
genuine = false;
if(data[2] & 0x80)
valid = true;
else
valid = false;
st->wMinute = data[2] & 0x3F;
st->wHour = data[3] & 0x1F;
if(data[3] & 0x80)
summer = true;
else
summer = false;
st->wDay = data[4] & 0x1F;
st->wDayOfWeek = (data[4] & 0xE0 ) >> 5;
if(st->wDayOfWeek) // if zero day of week not used.
st->wDayOfWeek = (st->wDayOfWeek + 1)%7;
st->wMonth = data[5] & 0x0F;
st->wYear = 2000 + (data[6] & 0x7F);
}

@ -0,0 +1,690 @@
/****************************************************************************
** File name : HTConfig.cpp
** Description : config parameter
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
//#include "StdAfx.h"
#include "HTPublic.h"
#include "HTConst.h"
#include "HTConfig.h"
#include "HTLogger.h"
static const char *_FILE_ = "HTConfig.cpp" ;
TConfig::TConfig()
{
b_monitor_enable = false ; // 监控标志 true:启用 false: 不启用
// database config parameter
memset(m_dbHostIP,0x00, sizeof(m_dbHostIP));
memset(m_dbName, 0x00, sizeof(m_dbName));
memset(m_dbUserName, 0x00, sizeof(m_dbUserName));
memset(m_dbUserPass, 0x00, sizeof(m_dbUserPass));
m_dbMaxConnect = 1 ;
m_dbMinConnect = 1 ;
m_dbPort = 3306 ;
memset(m_remote_addr, 0x00, sizeof(m_remote_addr));
m_remote_port = 2404 ;
// socket config
m_fd_limit = 1024 ;
m_recv_num = 1 ;
m_parse_num = 1 ;
m_opration_num = 1;
m_respone_num = 1 ;
}
TConfig::~TConfig()
{
b_monitor_enable = false ; // 监控标志 true:启用 false: 不启用
// database config parameter
memset(m_dbHostIP,0x00, sizeof(m_dbHostIP));
memset(m_dbName, 0x00, sizeof(m_dbName));
memset(m_dbUserName, 0x00, sizeof(m_dbUserName));
memset(m_dbUserPass, 0x00, sizeof(m_dbUserPass));
m_dbMaxConnect = 0 ;
m_dbMinConnect = 0 ;
m_dbPort = 3306 ;
memset(m_remote_addr, 0x00, sizeof(m_remote_addr));
m_remote_port = 2404 ;
m_recv_num = 0 ;
m_parse_num = 0 ;
m_opration_num = 0;
m_respone_num = 0 ;
}
// 设置数据库连接端口
void TConfig::setdbPort(unsigned int port)
{
m_dbPort= port;
}
// 设置数据库连接端口
unsigned int TConfig::getdbPort()
{
return m_dbPort;
}
// 设置数据库主机地址
void TConfig::setdbHostIP(char *pszDBHostIP)
{
if(!pszDBHostIP) return ;
strcpy(m_dbHostIP, pszDBHostIP);
}
// 获取数据库主机地址
char *TConfig::getdbHostIP()
{
return m_dbHostIP;
}
// 设置数据库最大连接池数
void TConfig::setdbMaxConnect(unsigned int max)
{
m_dbMaxConnect = max;
}
// 获取数据库最大连接池数
unsigned int TConfig::getdbMaxConnect()
{
return m_dbMaxConnect;
}
// 设置数据库最小连接池数
void TConfig::setdbMinConnect(unsigned int min)
{
m_dbMinConnect = min;
}
// 获取数据库最小连接池数
unsigned int TConfig::getdbMinConnect()
{
return m_dbMinConnect;
}
// 设置数据库服务名称
void TConfig::setdbName(char *pszDBName)
{
if(!pszDBName) return ;
strcpy(m_dbName, pszDBName);
}
// 获取数据库服务名称
char *TConfig::getdbName()
{
return m_dbName;
}
// 设置数据库用户名
void TConfig::setdbUserName(char *pszDBUserName)
{
if(!pszDBUserName) return ;
strcpy(m_dbUserName, pszDBUserName);
}
// 获取数据库用户名
char *TConfig::getdbUserName()
{
return m_dbUserName;
}
// 设置数据库用户密码
void TConfig::setdbUserPass(char *pszDBUserPass)
{
if(!pszDBUserPass) return ;
strcpy(m_dbUserPass, pszDBUserPass);
}
// 获取数据库用户密码
char *TConfig::getdbUserPass()
{
return m_dbUserPass;
}
// 设置本地服务器IP
void TConfig::setLocalAddr(char *pszAddr)
{
if (!pszAddr) return;
strcpy(m_local_addr, pszAddr);
}
// 获取本地服务器IP
char *TConfig::getLocalAddr()
{
return m_local_addr;
}
// 设置本地服务器端口
void TConfig::setLocalPort(unsigned short iPort)
{
m_local_port = iPort;
}
// 获取本地服务器端口
unsigned short TConfig::getLocalPort()
{
return m_local_port;
}
// 设置远程服务器IP
void TConfig::setRemoteAddr(char *pszAddr)
{
if(!pszAddr) return ;
strcpy(m_remote_addr, pszAddr);
}
// 获取远程服务器IP
char *TConfig::getRemoteAddr()
{
return m_remote_addr;
}
// 设置远程服务器端口
void TConfig::setRemotePort(unsigned short iPort)
{
m_remote_port = iPort;
}
// 获取远程服务器端口
unsigned short TConfig::getRemotePort()
{
return m_remote_port;
}
// socket 相关属性参数配置
void TConfig::setFdLimit(unsigned int iCount)
{
m_fd_limit = iCount;
}
unsigned int TConfig::getFdLimit()
{
return m_fd_limit;
}
void TConfig::setK(unsigned int k)
{
uK = k;
}
void TConfig::setW(unsigned int w)
{
uW = w;
}
unsigned int TConfig::getK()
{
return uK;
}
unsigned int TConfig::getW()
{
return uW;
}
void TConfig::setTimeout0(unsigned int t)
{
t0 = t;
}
void TConfig::setTimeout1(unsigned int t)
{
t1 = t;
}
unsigned int TConfig::getTimeout0()
{
return t0;
}
unsigned int TConfig::getTimeout1()
{
return t1;
}
void TConfig::setTimeout2(unsigned int t)
{
t2 = t;
}
unsigned int TConfig::getTimeout2()
{
return t2;
}
void TConfig::setTimeout3(unsigned int t)
{
t3 = t;
}
unsigned int TConfig::getTimeout3()
{
return t3;
}
void TConfig::setLogDebug(char yes)
{
m_logdebug = yes; // debug logger
}
void TConfig::setLogError(char yes)
{
m_logerror = yes; //error logger
}
void TConfig::setLogWarning(char yes)
{
m_logwarning = yes; // warning logger
}
void TConfig::setLogPack(char yes)
{
m_logpack = yes; // package print logger
}
void TConfig::setLogConsole(char yes)
{
m_logconsole = yes; // console print logger
}
void TConfig::setLogMessage(char yes)
{
m_logmessage = yes; // message print logger
}
char TConfig::isLogDebug(void)
{
return m_logdebug; // debug logger
}
char TConfig::isLogError(void)
{
return m_logerror; //error logger
}
char TConfig::isLogWarning(void)
{
return m_logwarning ; // warning logger
}
char TConfig::isLogPack(void)
{
return m_logpack ; // package print logger
}
char TConfig::isLogConsole(void)
{
return m_logconsole; // console print logger
}
char TConfig::isLogMessage(void)
{
return m_logmessage; // message print logger
}
void TConfig::setServerVersion(char *pver)
{
if(pver == NULL) {
strcpy(m_version, "000.00.000");
return ;
}
strcpy(m_version, pver);
}
char *TConfig::getServerVersion()
{
return m_version;
}
//JT/T809 服务数据交换监控
void TConfig::setMonitor(bool status)
{
b_monitor_enable = status;
}
bool TConfig::getMonitor()
{
return b_monitor_enable;
}
void TConfig::setRecvThreadNumber(unsigned int n)
{
m_recv_num = n ;
}
unsigned int TConfig::getRecvThreadNumber()
{
return m_recv_num ;
}
void TConfig::setParseThreadNumber(unsigned int n) // 解析104线程数
{
m_parse_num = n ;
}
unsigned int TConfig::getParseThreadNumber()
{
return m_parse_num ;
}
void TConfig::setOprationThreadNumber(unsigned int n) // 入库线程数
{
m_opration_num = n ;
}
unsigned int TConfig::getOprationThreadNumber()
{
return m_opration_num ;
}
void TConfig::setResponeThreadNumber(unsigned int n) // 应答线程数
{
m_respone_num = n ;
}
unsigned int TConfig::getResponeThreadNumber()
{
return m_respone_num ;
}
/*************************************************************************
Function iniGetString
Rectives a character string from the specified section in the
specified inifile
Param In :
pszSection : address of section
pszEntry : address of entry
uiBufLen : size of destination buffer
pszFileName: address of inifile name
Param Out :
pszRetBuf : destination buffer
Return Code :
0 : success
<0 : failed
*************************************************************************/
int TConfig::iniGetString(const char *pszSection, const char *pszEntry, char *pszRetBuf, unsigned int uiBufLen)
{
FILE *fpIni;
char szBuf[DEF_BUFFER_1K+1], *psz1, *psz2, *psz;
int iSectFlag, iLen;
if((fpIni= fopen(HT_CONFIG_FILE,"r")) == NULL) return (-1);
/*** check section ***/
iSectFlag= 0;
while(!feof(fpIni)) {
if (fgets(szBuf,DEF_BUFFER_1K,fpIni) == NULL) break;
psz= szBuf;
while(*psz!='[' && *psz!='#' && *psz!='\0') psz++;
if (*psz!='[') continue;
psz++;
while(*psz==' ' || *psz=='\t') psz++;
psz1= psz;
while(*psz!=']' && *psz!='\0') psz++;
if (*psz=='\0') continue;
while(*(psz-1)==' ' || *(psz-1)=='\t') psz--;
*psz= '\0';
if (!strcmp(psz1, pszSection)) {
iSectFlag= 1;
break;
}
}/*** while ***/
if (!iSectFlag) {
fclose(fpIni);
return (-1);
}
/*** check entry ***/
while(!feof(fpIni)) {
if(fgets(szBuf,DEF_BUFFER_1K,fpIni) == NULL) break;
psz= szBuf;
while(*psz==' ' || *psz=='\t') psz++;
if (*psz=='#' || *psz=='\0') continue;
if (*psz=='[') break;
psz1= psz;
while(*psz!='=' && *psz!='\0') psz++;
if (*psz=='\0') continue;
psz2= psz+1;
if (psz1==psz) continue;
while(*(psz-1)==' ' || *(psz-1)=='\t') psz--;
*psz= '\0';
#ifdef _WIN32
if(strcmp(psz1,pszEntry)) continue;
#else
if(strcasecmp(psz1, pszEntry)) continue;
#endif
fclose(fpIni);
psz= psz2;
while(*psz==' ' || *psz=='\t') psz++;
psz2= psz;
while(*psz!='#' && *psz!='\0' && !(*psz=='/' && (*(psz+1)=='*'||*(psz+1)=='/'))) psz++;
while(*(psz-1)==' ' || *(psz-1)=='\t' || *(psz-1)==0x0a || *(psz-1)==0x0d)
{
*(psz-1)= '\0';
psz--;
}
//*psz= '\0';
iLen= strlen(psz2);
if (iLen==0) return (-1);
if (iLen > (int)uiBufLen) iLen= uiBufLen;
memcpy(pszRetBuf, psz2, iLen);
*(pszRetBuf+iLen)= '\0';
return (0);
}
fclose(fpIni);
return (-1);
}
// 加载服务配置参数
bool TConfig::getIniConfig()
{
int iRet = -1;
char szTmp[64];
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_LOGGER","logger", szTmp, sizeof(szTmp))) < 0) {
printf("get logger parameter failed, %s\n", szTmp);
}
if(strstr(szTmp, "debug") == NULL) setLogDebug(0x00);
else setLogDebug(0x01);
if(strstr(szTmp, "error") == NULL) setLogError(0x00);
else setLogError(0x01);
if(strstr(szTmp, "warning") == NULL) setLogWarning(0x00);
else setLogWarning(0x01);
if(strstr(szTmp, "package") == NULL) setLogPack(0x00);
else setLogPack(0x01);
if(strstr(szTmp, "console") == NULL) setLogConsole(0x00);
else setLogConsole(0x01);
if(strstr(szTmp, "message") == NULL) setLogMessage(0x00);
else setLogMessage(0x01);
////////////////////////////////////////////////////////////////////////////
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_MONITOR","monitor_enable", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get monitor_enable parameter failed");
return false;
}
if(stringcasecmp(szTmp, "true") == 0)
setMonitor(true); // 启用监控报文功能
else setMonitor(false) ;
////////////////////////////////////////////////////////////////////////////
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_VERSION","ht_server_version", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get ht_server_version parameter failed");
return false;
}
setServerVersion(szTmp);
////////////////////////////////////////////////////////////////////////////
// 加载数据库配置参数
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_host_addr", szTmp, sizeof(szTmp))) < 0) {
// vPrtLogMsg(LOG_ERROR, iRet, "get db_host_addr parameter failed");
// return false;
setdbHostIP((char*)"127.0.0.1");
}
else setdbHostIP(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_host_port", szTmp, sizeof(szTmp))) < 0) {
//vPrtLogMsg(LOG_ERROR, iRet, "get db_host_port parameter failed");
//return false;
setdbPort(3306);
}
else setdbPort((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_name", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get db_name parameter failed");
return false;
}
setdbName(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_username", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get db_username parameter failed");
return false;
}
setdbUserName(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_password", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get db_password parameter failed");
return false;
}
setdbUserPass(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_min_conn", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get db_min_conn parameter failed");
return false;
}
setdbMinConnect((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_DATABASE","db_max_conn", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get db_max_conn parameter failed");
return false;
}
setdbMaxConnect((unsigned int)atoi(szTmp));
////////////////////////////////////////////////////////////////////////////
// 加载服务器端参数
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iniGetString("HT_LOCAL_HOST", "local_host_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get local_host_addr parameter failed");
return false;
}
setLocalAddr(szTmp);
memset(szTmp, 0x00, sizeof(szTmp)); // 服务器端口
if ((iRet = iniGetString("HT_LOCAL_HOST", "local_tcp_port", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get local_tcp_port parameter failed,set define:2404!");
strcpy(szTmp, "2404");
//return false;
}
setLocalPort((unsigned int)atoi(szTmp));
// 加载服务器端参数
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_REMOTE_HOST","remote_host_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get remote_host_addr parameter failed");
return false;
}
setRemoteAddr(szTmp);
memset(szTmp, 0x00, sizeof(szTmp)); // 服务器端口
if((iRet = iniGetString("HT_REMOTE_HOST","remote_host_port", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get remote_host_port parameter failed,set define:2404!");
strcpy(szTmp, "2404") ;
//return false;
}
setRemotePort((unsigned int)atoi(szTmp));
////////////////////////////////////////////////////////////////////////////
// socket 相关属性参数配置
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_SOCKET","max_epoll_limit", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get max_epoll_limit parameter failed");
return false;
}
setFdLimit((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iniGetString("HT_SOCKET", "timeout_t0", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get timeout_t0 parameter failed");
return false;
}
setTimeout0((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_SOCKET","timeout_t1", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get timeout_t1 parameter failed");
return false;
}
setTimeout1((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_SOCKET","timeout_t2", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get timeout_t2 parameter failed");
return false;
}
setTimeout2((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_SOCKET","timeout_t3", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get timeout_t3 parameter failed");
return false;
}
setTimeout3((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iniGetString("HT_SOCKET", "iec_k", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_k parameter failed");
return false;
}
setK((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iniGetString("HT_SOCKET", "iec_w", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_w parameter failed");
return false;
}
setW((unsigned int)atoi(szTmp));
////////////////////////////////////////////////////////////////////////////
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_THREAD_NUMBER","thread_recv_num", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get thread_recv_num parameter failed");
return false;
}
setRecvThreadNumber((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_THREAD_NUMBER","thread_parse_num", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get thread_parse_num parameter failed");
return false;
}
setParseThreadNumber((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp));
if((iRet = iniGetString("HT_THREAD_NUMBER","thread_opration_num", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get thread_opration_num parameter failed");
return false;
}
setOprationThreadNumber((unsigned int)atoi(szTmp));
memset(szTmp, 0x00, sizeof(szTmp)); //
if((iRet = iniGetString("HT_THREAD_NUMBER","thread_respone_num", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get thread_respone_num parameter failed");
return false;
}
setResponeThreadNumber((unsigned int)atoi(szTmp));
return true;
}
void TConfig::showConfig()
{
// vPrtLogMsg(LOG_DEBUG, 0, "local_server_name=%s local_host_addr=%s local_tcp_port=%d\n"
// "db_host_addr=%s db_port=%d db_name=%s db_username=%s db_password=%s\n"
// "db_min_conn=%d db_max_conn=%d max_epoll_limit=%d loacl_active_interval=%d\n"
// "local_tcp_recv_timeout=%d local_udp_recv_timeout=%d\n"
// //"gov_user_name=%s gov_user_pass=%s gov_host_addr=%s gov_tcp_port=%d gov_tcp_recv_timeout=%d",
// "gov_tcp_recv_timeout=%d",
// m_LocalName, m_LocalAddr, m_LocalTcpPort,
// m_dbHostIP,m_dbPort,m_dbName,m_dbUserName,m_dbUserPass,m_dbMinConnect,m_dbMaxConnect,
// m_fd_limit,m_active_interval,m_tcp_recv_timeout,m_udp_recv_timeout,
// //m_GovUserName,m_GovUserPass,m_GovHostAddr,m_GovTcpPort,m_GovTcpRecvTimeout);
// m_GovTcpRecvTimeout);
}

@ -0,0 +1,458 @@
/****************************************************************************
** File name : HTDatabase.cpp
** Description : mysql database member function
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
#include "HTDatabase.h"
static const char *_FILE_ = "HTDatabase.cpp" ;
CDBMySQL::CDBMySQL()
{
strcpy(m_host,g_TConfig.getdbHostIP());
strcpy(m_db, g_TConfig.getdbName());
strcpy(m_user,g_TConfig.getdbUserName());
strcpy(m_password,g_TConfig.getdbUserPass());
m_port = g_TConfig.getdbPort();
m_min = g_TConfig.getdbMinConnect();
mutex_create(m_csList);
}
CDBMySQL::CDBMySQL(const char *host, const char *user, const char *password, const char *db, unsigned int port/* =3306 */)
{
strcpy(m_host, host);
strcpy(m_user, user);
strcpy(m_password, password);
strcpy(m_db, db);
m_port = port;
m_min = g_TConfig.getdbMinConnect();
mutex_create(m_csList);
}
CDBMySQL::~CDBMySQL()
{
dbFreeConnectPool();
}
CDBMySQL* CDBMySQL::Instance()
{
if(p_dbHandle == NULL)
{
try {
p_dbHandle = new CDBMySQL();
}
catch(...) {
vPrtLogMsg(LOG_WARNG, RET_FAIL, "CDBMySQL::Instance exceptions.");
}
}
return p_dbHandle;
}
void CDBMySQL::dbFreeConnectPool()
{
ITER_CONNECTION_HANDLE_LIST iter;
for (iter=m_lsBusyList.begin(); iter != m_lsBusyList.end(); iter++)
{
mysql_close((*iter));
}
for (iter=m_lsIdleList.begin(); iter != m_lsIdleList.end(); iter++)
{
mysql_close((*iter));
}
mysql_library_end();
mutex_close(m_csList);
}
bool CDBMySQL::dbConnectPool()
{
try
{
vPrtLogMsg(LOG_DEBUG,0, "connect database:%s/%s@%s -h %s:%d start...", m_user,m_password,m_db,m_host,m_port);
for (int i=0; i < (int)m_min; ++i)
{
char value = 1;
MYSQL *pMySql = mysql_init((MYSQL*)NULL);
//mysql_options(pMySql, MYSQL_SET_CHARSET_NAME, "gbk");
mysql_options(pMySql, MYSQL_OPT_RECONNECT, (char *)&value); //设置自动连接
if (pMySql != NULL)
{
if (!mysql_real_connect(pMySql,m_host,m_user,m_password,m_db,m_port,NULL,0))
{
vPrtLogMsg(LOG_ERROR,errno, "connect database:%s/%s@%s -h %s:%d failed! err:%s", m_user,m_password,m_db,m_host,m_port, getLastError(pMySql));
return false;
}
mysql_set_character_set(pMySql, "GBK");
m_lsIdleList.push_back(pMySql);
}
else{
vPrtLogMsg(LOG_ERROR,errno, "connect database:%s/%s@%s -h %s:%d failed! err:%s", m_user,m_password,m_db,m_host,m_port, getLastError(pMySql));
}
}
}
catch (...)
{
vPrtLogMsg(LOG_ERROR,errno, "connect database:%s/%s@%s -h %s:%d failed!", m_user,m_password,m_db,m_host,m_port);
return false;
}
return true;
}
MYSQL* CDBMySQL::GetIdleMySql()
{
MYSQL* pMySql = NULL;
mutex_lock(m_csList);
if (m_lsIdleList.size() > 0)
{
pMySql = m_lsIdleList.front();
if (pMySql ) {
m_lsIdleList.pop_front();
m_lsBusyList.push_back(pMySql);
mysql_ping(pMySql); // 检查连接是否正常
}
}
else
{
pMySql = NULL;
}
mutex_unlock(m_csList);
return pMySql;
}
void CDBMySQL::SetIdleMysql(MYSQL* pMySql)
{
mutex_lock(m_csList);
if (pMySql) {
if (m_lsBusyList.size() > 0)
m_lsBusyList.remove(pMySql);
m_lsIdleList.push_back(pMySql);
}
mutex_unlock(m_csList);
}
//bStart = false : close auto commit
// = true : open auto commit
bool CDBMySQL::dbAutoCommit(MYSQL *pMysql, bool bStart) // 开始事务处理
{
return mysql_autocommit(pMysql, bStart) ? false : true;
}
bool CDBMySQL::dbCommit(MYSQL *pMysql)
{
return mysql_commit(pMysql) ? false : true;
}
MYSQL_RES* CDBMySQL::SelectRecord(const char *szSql)
{
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
if(mysql_query(pMySql,szSql))
{
vPrtLogMsg(LOG_ERROR,errno, "SelectRecord failed! SQL:[%s] err:%s", szSql, getLastError(pMySql));
SetIdleMysql(pMySql);
return NULL;
}
MYSQL_RES *myquery = NULL;
if(!(myquery = mysql_store_result(pMySql))) {
vPrtLogMsg(LOG_ERROR,errno, "SelectRecord failed! SQL:[%s] err:%s", szSql, getLastError(pMySql));
myquery = NULL;
}
SetIdleMysql(pMySql);
return myquery;
}
bool CDBMySQL::InsertRecordBitch(const char pszSql[][256], int count)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
dbAutoCommit(pMySql, false); // 开始批量提交事务
//mysql_query(pMySql, "START TRANSACTION"); // 开启事务, 如果没有开启事务,那么效率会变得非常低下!
// return 0: successed !0: failed
for (int n = 0; n < count; n++)
{
if (!mysql_query(pMySql, pszSql[n]))
{
bRet = true;
}
else {
vPrtLogMsg(LOG_ERROR, errno, "InsertRecordBitch failed! ERROR SQL[%d]:[%s] err:%s", n+1, pszSql[n], getLastError(pMySql));
}
}
dbCommit(pMySql);
dbAutoCommit(pMySql, true); // 结束批量提交事务
SetIdleMysql(pMySql);
return bRet;
}
bool CDBMySQL::AddInsertRecord(MYSQL *pHandle, const char *szSql)
{
bool bRet = false;
// return 0: successed !0: failed
if (!mysql_query(pHandle, szSql))
{
bRet = true;
}
else {
vPrtLogMsg(LOG_ERROR, errno, "AddInsertRecord failed! SQL:[%s] err:%s", szSql, getLastError(pHandle));
}
return bRet;
}
bool CDBMySQL::InsertRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
// return 0: successed !0: failed
if(!mysql_query(pMySql,szSql))
{
bRet = true;
}
else {
vPrtLogMsg(LOG_ERROR,errno, "InsertRecord failed! SQL:[%s] err:%s", szSql, getLastError(pMySql));
}
SetIdleMysql(pMySql);
return bRet;
}
bool CDBMySQL::UpdateRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(!mysql_query(pMySql,szSql))
{
bRet = true;
}
else {
vPrtLogMsg(LOG_ERROR,errno, "UpdateRecord failed! SQL:[%s] err:%s", szSql, getLastError(pMySql));
}
SetIdleMysql(pMySql);
return bRet;
}
bool CDBMySQL::DelRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(!mysql_query(pMySql,szSql))
{
bRet = true;
}
else {
vPrtLogMsg(LOG_ERROR,errno, "DelRecord failed! SQL:[%s] err:%s", szSql, getLastError(pMySql));
}
SetIdleMysql(pMySql);
return bRet;
}
bool CDBMySQL::SelectDB(const char *szDB)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL) return false;
if (mysql_select_db(pMySql,szDB)) {
vPrtLogMsg(LOG_ERROR,errno, "SelectDB failed! dbname:[%s] err:%s", szDB, getLastError(pMySql));
bRet = false;
}
else bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
my_ulonglong CDBMySQL::GetRowNum(MYSQL_RES *myquery)
{
return mysql_num_rows(myquery);
}
MYSQL_ROW CDBMySQL::GetRecord(MYSQL_RES *myquery)
{
m_row = mysql_fetch_row(myquery);
return m_row;
}
unsigned int CDBMySQL::GetFieldNum(MYSQL_RES *myquery)
{
return mysql_num_fields(myquery);
}
void CDBMySQL::FreeRecord(MYSQL_RES *myquery)
{
mysql_free_result(myquery);
}
//int CDBMySQL::CreateDB(char *db)
//{
// return mysql_create_db(&m_mysql,db);
//}
void CDBMySQL::SeekData(MYSQL_RES *myquery, int offset)
{
mysql_data_seek(myquery,offset);
}
char * CDBMySQL::getLastError(MYSQL *pMySql)
{
return const_cast<char *>(mysql_error(pMySql));
}
bool CDBMySQL::IsEnd(MYSQL_RES *myquery)
{
return (mysql_eof(myquery)?true:false);
}
char* CDBMySQL::GetFieldName(MYSQL_RES *myquery, int FieldNum)
{
m_field = mysql_fetch_field_direct(myquery, FieldNum);
return m_field->name;
}
char * CDBMySQL::GetClientInfo()
{
return const_cast<char *>(mysql_get_client_info());
}
char* CDBMySQL::GetHostInfo()
{
char *p = NULL;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
p = const_cast<char *>(mysql_get_host_info(pMySql));
SetIdleMysql(pMySql);
return p ;
}
int CDBMySQL::GetProtocolInfo()
{
int iRet = 0;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return 0;
}
iRet = mysql_get_proto_info(pMySql);
SetIdleMysql(pMySql);
return iRet;
}
char* CDBMySQL::GetServerInfo()
{
static char szRet[1024] = {0};
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
strcpy(szRet, const_cast<char *>(mysql_get_server_info(pMySql)));
SetIdleMysql(pMySql);
return szRet;
}
char* CDBMySQL::GetState()
{
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL) return NULL;
static char szRet[1024] = {0} ;
strcpy(szRet,const_cast<char *>(mysql_stat(pMySql)));
SetIdleMysql(pMySql);
return szRet;
}
bool CDBMySQL::SetCharset()
{
bool bRet = false;
//char szSql[50] = {0};
//strcpy(szSql, "set names gb2312");
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL) return false;
if(mysql_set_character_set(pMySql, "GBK"))
//if (mysql_query(pMySql, szSql))
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
//LOCK TABLES tbl1 READ, tbl2 WRITE
bool CDBMySQL::LockTable(const char *TableName, const char *Priority)
{
bool bRet = false;
char szSql[50] = {0} ;
sprintf(szSql, "LOCK TABLES %s %s", TableName, Priority);
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL) return false;
if (mysql_query(pMySql, szSql))
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
bool CDBMySQL::UnlockTable()
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL) return false;
if(mysql_query(pMySql,"UNLOCK TABLES")) bRet = true;
SetIdleMysql(pMySql);
return bRet;
}

@ -0,0 +1,78 @@
/****************************************************************************
** File name : FLTGlobal.h
** Description : global variable define
** Create date : 2012.10.10
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#pragma warning (disable:4786)
//#include "StdAfx.h"
#include "HTGlobal.h"
TConfig g_TConfig ;
TTcpSocket g_Tcp;
int g_Running;
ST_IEC104_CTRL g_IecCtrl; // socket linker info and status
mutex g_IecCtrl_mutex; // socket linker on mutex
int g_seqno; // 与MEC之间交换的流水号
mutex g_seq_mutex; // 流水号
map<string, ST_BYQWORK_STATUS> g_map_work; // 主变工作状态缓存
mutex g_map_work_mutex; // 主变工作状态缓存队列锁
//map<string,ST_BYQ_CACHE> g_map_byq; // 变压器缓存数据
map<string, ST_BYQ_RUN_STATE_THRESHOLD> g_map_thres_byq;
mutex g_map_byq_mutex; // 变压器缓存数据信息队列锁
//map<string,ST_GIS_CACHE> g_map_gis; // GIS缓存数据
//mutex g_map_gis_mutex; // GIS缓存数据信息队列锁
multimap<string, ST_DEV_RELATION> g_map_relation; // 主设备与外挂设备关系
mutex g_map_relation_mutex; // GIS缓存数据信息队列锁
//map<string, ST_GIS_IEC104_DATA> g_map_gis_104; // GIS最近一次104上传数据缓存
//mutex g_map_gis_104_mutex;
//map<string, ST_BLQ_CACHE> g_map_blq; // BLQ缓存数据
//mutex g_map_blq_mutex; // BLQ缓存数据信息队列锁
map<unsigned int, ST_IECPOINT_TABLE> g_map_iec; // 104点表报文解析缓存数据
mutex g_map_iec_mutex; // 104报文解析缓存数据信息队列锁
map<unsigned int, ST_SADR_MATCH> g_map_sadr; // 点表匹配关系
mutex g_map_sadr_mutex;
map<string, ST_IMG_THRESHOLD> g_map_img_thres; // 图片识别阈值
mutex g_map_img_thres_mutex;
map<string, ST_DEVICE_TIME_STAT> g_map_dev_time_stat;
mutex g_map_dev_time_stat_mutex;
map<unsigned int, ST_BREAK_EQM_CODE> g_map_gis_state; // 断路器状态位与电流电压关系匹配表
mutex g_map_gis_state_mutex;
pthread_t thread_handle_parse; // 104报文解析线程
//pthread_t thread_handle_setdb; // 入库线程
pthread_t thread_handle_timer; // 超时监测线程
//pthread_t thread_handle_getdata; // 数据提取线程
pthread_t thread_handle_client; // 客户端链接线程
pthread_t thread_handle_warning; // 报警处理及入库线程句柄
pthread_t thread_handle_origin; // 原始数据如何线程句柄
pthread_t thread_handle_pingce; // IEC104评测数据入库线程句柄
pthread_t thread_handle_gishold; // 断路器断开数据入库线程句柄
pthread_t thread_handle_active; // 心跳线程
pthread_t thread_handle_linkmgr; // 链路管理线程
pthread_t thread_handle_cache; // 内存同步线程句柄
pthread_t thread_handle_opecvimg; // 图片识别线程句柄

@ -0,0 +1,682 @@
/****************************************************************************
** File name : HTIEC104.h
** Description : define 104 worker thread group
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
//#include <string.h>
#include "HTGlobal.h"
#include "HTIEC104.h"
static const char *_FILE_ = "HTIEC104.cpp";
static FILE *fpIec = NULL; // iec104 config file handle.
static ST_IEC104_CONF g_iec_conf;
static time_t g_Internal_time;
list<ST_RECVPKG> g_list_pack;
mutex g_list_pack_mutex;
list<ST_DB_DATA> g_list_dbset;
mutex g_list_dbset_mutex;
list<ST_IECPOINT_TABLE> g_list_origin;
mutex g_list_origin_mutex;
list<ST_IECPOINT_TABLE> g_list_pingce;
mutex g_list_pingce_mutex;
list<ST_IECPOINT_TABLE> g_list_warn;
mutex g_list_warn_mutex;
mutex g_sendno_mutex;
CIEC104::CIEC104()
{
}
CIEC104::~CIEC104()
{
}
static void vPrtListCount()
{
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pack count:%d", g_list_pack.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_dbset count:%d", g_list_dbset.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_origin count:%d", g_list_origin.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_pingce count:%d", g_list_pingce.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_list_warn count:%d", g_list_warn.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_thres_byq count:%d", g_map_thres_byq.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_relation count:%d", g_map_relation.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_iec count:%d", g_map_iec.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_img_thres count:%d", g_map_img_thres.size());
vPrtLogMsg(LOG_WARNG, RET_OK, "-----> g_map_sadr count:%d", g_map_sadr.size());
}
/*************************************************************************
Function iniGetString
Rectives a character string from the specified section in the
specified inifile
Param In :
pszSection : address of section
pszEntry : address of entry
uiBufLen : size of destination buffer
pszFileName: address of inifile name
Param Out :
pszRetBuf : destination buffer
Return Code :
0 : success
<0 : failed
*************************************************************************/
static int iGetString(const char *pszSection, const char *pszEntry, char *pszRetBuf, unsigned int uiBufLen)
{
//FILE *fpIni;
char szBuf[DEF_BUFFER_1K + 1], *psz1, *psz2, *psz;
int iSectFlag, iLen;
if (fpIec == NULL) {
if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL)
return (-1);
}
fseek(fpIec, 0, SEEK_SET);
/*** check section ***/
iSectFlag = 0;
while (!feof(fpIec)) {
if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break;
psz = szBuf;
while (*psz != '[' && *psz != '#' && *psz != '\0') psz++;
if (*psz != '[') continue;
psz++;
while (*psz == ' ' || *psz == '\t') psz++;
psz1 = psz;
while (*psz != ']' && *psz != '\0') psz++;
if (*psz == '\0') continue;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--;
*psz = '\0';
if (!strcmp(psz1, pszSection)) {
iSectFlag = 1;
break;
}
}/*** while ***/
if (!iSectFlag) {
//fclose(fpIni);
return (-1);
}
/*** check entry ***/
while (!feof(fpIec)) {
if (fgets(szBuf, DEF_BUFFER_1K, fpIec) == NULL) break;
psz = szBuf;
while (*psz == ' ' || *psz == '\t') psz++;
if (*psz == '#' || *psz == '\0') continue;
if (*psz == '[') break;
psz1 = psz;
while (*psz != '=' && *psz != '\0') psz++;
if (*psz == '\0') continue;
psz2 = psz + 1;
if (psz1 == psz) continue;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--;
*psz = '\0';
#ifdef _WIN32
if (strcmp(psz1, pszEntry)) continue;
#else
if (strcasecmp(psz1, pszEntry)) continue;
#endif
//fclose(fpIni);
psz = psz2;
while (*psz == ' ' || *psz == '\t') psz++;
psz2 = psz;
while (*psz != '#' && *psz != '\0' && !(*psz == '/' && (*(psz + 1) == '*' || *(psz + 1) == '/'))) psz++;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t' || *(psz - 1) == 0x0a || *(psz - 1) == 0x0d)
{
*(psz - 1) = '\0';
psz--;
}
//*psz= '\0';
iLen = strlen(psz2);
if (psz2[iLen - 1] == 0x0a || psz2[iLen - 1] == 0x0d) psz2[iLen - 1] = 0x00;
if (iLen == 0) return (0); //return (-1); // 参数未设置,即参数值为空的情况
if (iLen > (int)uiBufLen) iLen = uiBufLen;
memcpy(pszRetBuf, psz2, iLen);
*(pszRetBuf + iLen) = '\0';
return (0);
}
//fclose(fpIni);
return (-1);
}
static void setSadrMatchRelations(unsigned int key, ST_SADR_MATCH *pstAdr)
{
ST_SADR_MATCH stAdr;
memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH));
if (key <= 0) return; // key=0时表示104配置文件中无此点表地址、地址为空的情况
stAdr.eqm_type = pstAdr->eqm_type;
stAdr.count = pstAdr->count;
stAdr.psadr = (ST_MATCH_LIST*)calloc(pstAdr->count, sizeof(ST_MATCH_LIST));
memcpy(stAdr.psadr, pstAdr->psadr, (pstAdr->count * sizeof(ST_MATCH_LIST)));
mutex_lock(g_map_sadr_mutex);
g_map_sadr.insert(map<unsigned int, ST_SADR_MATCH>::value_type(key, stAdr));
mutex_unlock(g_map_sadr_mutex);
}
// 加IEC104业务配置文件数据
static bool iGetIEC104Conf()
{
int iRet = -1, i;
char szTmp[512], szSection[128];
memset(&g_iec_conf, 0x00, sizeof(ST_IEC104_CONF)); // 初始化IEC104配置.
// 打开配置文件,准备加载配置参数
if (fpIec == NULL) {
if ((fpIec = fopen(IEC_CONFIMG_FILE, "r")) == NULL) {
vPrtLogMsg(LOG_ERROR, errno, "open config file: %s failed!", HT_CONFIMG_FILE);
return NULL;
}
}
// 获取变压器配置项的个数
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_DEVCOUNT", "iec_byq_count", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_byq_count parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.iec_byq_count = (unsigned int)atoi(szTmp);
// 申请变压器设备编码缓冲区
g_iec_conf.pstByqCode = (ST_BYQ_EQM_CODE*)calloc(g_iec_conf.iec_byq_count, sizeof(ST_BYQ_EQM_CODE));
if (!g_iec_conf.pstByqCode) {
vPrtLogMsg(LOG_ERROR, iRet, "calloc byq_eqm_code cache size: %d failed!", g_iec_conf.iec_byq_count * sizeof(ST_BYQ_EQM_CODE));
fclose(fpIec);
return false;
}
// 获取断路器配置项的个数
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_DEVCOUNT", "iec_break_count", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_break_count parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.iec_break_count = (unsigned int)atoi(szTmp);
// 申请断路器设备编码缓冲区
g_iec_conf.pstBrkCode = (ST_BREAK_EQM_CODE*)calloc(g_iec_conf.iec_break_count, sizeof(ST_BREAK_EQM_CODE));
if (!g_iec_conf.pstBrkCode) {
vPrtLogMsg(LOG_ERROR, iRet, "calloc brk_eqm_code cache size: %d failed!", g_iec_conf.iec_break_count * sizeof(ST_BREAK_EQM_CODE));
fclose(fpIec);
return false;
}
// 获取站点ID配置项
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_DEVCOUNT", "iec_site_id", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_site_id parameter failed!");
fclose(fpIec);
return false;
}
strcpy((char*)g_iec_conf.site_id , szTmp);
vPrtLogMsg(LOG_DEBUG, 0, "get iec_byq_count config count: byq_cnt:%d,gis_cnt:%d,site_id:%s",
g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count, szTmp);
// 104时间保存间隔时间(s)
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("COMM_SAVE_INTERNAL", "DATA_SAVE_INTERNAL", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get DATA_SAVE_INTERNAL parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.save_internal = (unsigned int)atoi(szTmp);
// 获取公共地址配置
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "iec_global_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get iec_global_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.iec_global_addr = (unsigned short)atoi(szTmp);
// 获取YC地址配置
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_start_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get yx_start_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.yx_start_addr = (unsigned int)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "yx_stop_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get yx_stop_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.yx_stop_addr = (unsigned int)atoi(szTmp);
// 获取JB地址配置
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_start_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get jb_start_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.jb_start_addr = (unsigned int)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "jb_stop_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get jb_stop_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.jb_stop_addr = (unsigned int)atoi(szTmp);
// 获取YC地址配置
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_start_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get yc_start_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.yc_start_addr = (unsigned int)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("IEC_OBJS_ADDR", "yc_stop_addr", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get yc_stop_addr parameter failed!");
fclose(fpIec);
return false;
}
g_iec_conf.yc_stop_addr = (unsigned int)atoi(szTmp);
// 获取BYQ配置各项参数
for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++)
{
snprintf(szSection, sizeof(szSection), "IEC_BYQ_CODE_%02d", i + 1);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "EQM_CODE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE parameter failed", szSection);
fclose(fpIec);
return false;
}
strcpy((char*)g_iec_conf.pstByqCode[i].szEqmCode, szTmp);
// 主变高压侧电压、电流点位HIGH_VOLTAGE, HIGH_CURRENT = 16387
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "HIGH_VOLTAGE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_VOLTAGE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiHighVoltage = atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "HIGH_CURRENT", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: HIGH_CURRENT parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiHighCurrent = atoi(szTmp);
//主变低压(出口)侧电压、电流点位 LOW_VOLTAGE = 16700 LOW_CURRENT = 16701
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "LOW_VOLTAGE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_VOLTAGE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiLowVoltage = atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "LOW_CURRENT", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: LOW_CURRENT parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiLowCurrent = atoi(szTmp);
//# 运行工况点位
//# 主变冷却水进口压力点位 COOL_WATER_PRESS_ENTRY = 16365
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_ENTRY parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry = atoi(szTmp);
//# 主变冷却水出口压力点位 COOL_WATER_PRESS_OUTER = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "COOL_WATER_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_PRESS_OUTER parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter = atoi(szTmp);
//# 主变冷却水进口温度点位 COOL_WATER_TEMP_ENTRY = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_ENTRY parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry = atoi(szTmp);
//# 主变冷却水出口温度点位 COOL_WATER_TEMP_OUTER = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "COOL_WATER_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: COOL_WATER_TEMP_OUTER parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter = atoi(szTmp);
//# 主变油进口压力点位 OIL_PRESS_ENTRY = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_PRESS_ENTRY", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_ENTRY parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilPressEntry = atoi(szTmp);
//# 主变油出口压力点位 OIL_PRESS_OUTER = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_PRESS_OUTER", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_PRESS_OUTER parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilPressOuter = atoi(szTmp);
//# 主变油进口温度点位 OIL_TEMP_ENTRY = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_TEMP_ENTRY", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_ENTRY parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilTempEntry = atoi(szTmp);
//# 主变油出口温度点位 OIL_TEMP_OUTER = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_TEMP_OUTER", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMP_OUTER parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilTempOuter = atoi(szTmp);
//# 主变绕组温度点位 WINDING_TEMPERATURE = 16366
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "WINDING_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: WINDING_TEMPERATURE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiWindingTemp = atoi(szTmp);
//# 主变油温点位 OIL_TEMPERATURE = 16405
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TEMPERATURE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilTemperature = atoi(szTmp);
//# 主变顶层油温点位 OIL_TOP_TEMPERATURE = 16405
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_TOP_TEMPERATURE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_TOP_TEMPERATURE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilTopTemp = atoi(szTmp);
//# 主变油位点位 OIL_POSITION = 16406
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_POSITION", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_POSITION parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilPosition = atoi(szTmp);
//# 主变油枕油位点位 OIL_OILPILLOW_OILLEVEL = 16406
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "OIL_OILPILLOW_OILLEVEL", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: OIL_OILPILLOW_OILLEVEL parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstByqCode[i].uiOilPillowLevel = atoi(szTmp);
}
// 获取断路器配置各项参数
for (i = 0; i < (int)g_iec_conf.iec_break_count; i++)
{
ST_BREAK_EQM_CODE stGisState;
memset(&stGisState, 0x00, sizeof(ST_BREAK_EQM_CODE));
snprintf(szSection, sizeof(szSection), "IEC_BREAK_CODE_%02d", i + 1);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "EQM_CODE_A", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_A parameter failed", szSection);
fclose(fpIec);
return false;
}
strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeA, szTmp);
strcpy((char*)stGisState.szEqmCodeA, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "EQM_CODE_B", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_B parameter failed", szSection);
fclose(fpIec);
return false;
}
strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeB, szTmp);
strcpy((char*)stGisState.szEqmCodeB, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "EQM_CODE_C", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: EQM_CODE_C parameter failed", szSection);
fclose(fpIec);
return false;
}
strcpy((char*)g_iec_conf.pstBrkCode[i].szEqmCodeC, szTmp);
strcpy((char*)stGisState.szEqmCodeC, szTmp);
// 断开状态点位,开关的遥信点位
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "STATE_SIGNAL", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: STATE_SIGNAL parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstBrkCode[i].uiStateSadr = atoi(szTmp);
stGisState.uiStateSadr = atoi(szTmp);
// 断开电压点位
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "ABORT_VOLTAGE", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_VOLTAGE parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstBrkCode[i].uiAbortVoltage = atoi(szTmp);
stGisState.uiAbortVoltage = atoi(szTmp);
// 断开电流点位
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "ABORT_CURRENT", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: ABORT_CURRENT parameter failed", szSection);
fclose(fpIec);
return false;
}
g_iec_conf.pstBrkCode[i].uiAbortCurrent = atoi(szTmp);
stGisState.uiAbortCurrent = atoi(szTmp);
mutex_lock(g_map_gis_state_mutex); // 断路器遥信状态下,对应其电流电压点位
g_map_gis_state.insert(map<unsigned int, ST_BREAK_EQM_CODE>::value_type(stGisState.uiStateSadr, stGisState));
mutex_unlock(g_map_gis_state_mutex);
}
fclose(fpIec);
// 根据配置,建立点表地址匹配关系map
for (i = 0; i < (int)g_iec_conf.iec_byq_count; i++)
{
// 主变高压侧电流电压匹配关系
ST_SADR_MATCH stAdr;
memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH));
stAdr.eqm_type = 1;
stAdr.count = 2;
stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST));
stAdr.psadr[0].group = 1; // 高压侧电流、电压组
stAdr.psadr[0].btype = 1; // 高压侧电流
stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiHighCurrent;
stAdr.psadr[1].group = 1; // 高压侧电流、电压组
stAdr.psadr[1].btype = 2; // 高压侧电压
stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiHighVoltage;
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighVoltage, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiHighCurrent, &stAdr);
if (stAdr.psadr) free(stAdr.psadr);
stAdr.psadr = NULL;
// 主变低压侧电流电压匹配关系
stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST));
stAdr.psadr[0].group = 2; // 低压侧电流、电压组
stAdr.psadr[0].btype = 1; //低压侧电流
stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiLowCurrent;
stAdr.psadr[1].group = 2; // 低压侧电流、电压组
stAdr.psadr[1].btype = 2; //低压侧电压
stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiLowVoltage;
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowVoltage, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiLowCurrent, &stAdr);
if (stAdr.psadr) free(stAdr.psadr);
stAdr.psadr = NULL;
// 运行工况
stAdr.eqm_type = 1;
stAdr.count = 13;
stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST));
stAdr.psadr[0].group = 3; // 运行工况组
stAdr.psadr[0].btype = 1; // 进口水压力
stAdr.psadr[0].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry;
stAdr.psadr[1].group = 3; // 运行工况组
stAdr.psadr[1].btype = 2; // 出口水压力
stAdr.psadr[1].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter;
stAdr.psadr[2].group = 3; // 运行工况组
stAdr.psadr[2].btype = 3; // 主变本体油位数
stAdr.psadr[2].sadr = g_iec_conf.pstByqCode[i].uiOilPosition;
stAdr.psadr[3].group = 3; // 运行工况组
stAdr.psadr[3].btype = 4; // 主变本体油温数
stAdr.psadr[3].sadr = g_iec_conf.pstByqCode[i].uiOilTemperature;
stAdr.psadr[4].group = 3; // 运行工况组
stAdr.psadr[4].btype = 5; // 进口水温度
stAdr.psadr[4].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry;
stAdr.psadr[5].group = 3; // 运行工况组
stAdr.psadr[5].btype = 6; // 出口水温度
stAdr.psadr[5].sadr = g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter;
stAdr.psadr[6].group = 3; // 运行工况组
stAdr.psadr[6].btype = 7; // 进口油压力
stAdr.psadr[6].sadr = g_iec_conf.pstByqCode[i].uiOilPressEntry;
stAdr.psadr[7].group = 3; // 运行工况组
stAdr.psadr[7].btype = 8; // 出口油压力
stAdr.psadr[7].sadr = g_iec_conf.pstByqCode[i].uiOilPressOuter;
stAdr.psadr[8].group = 3; // 运行工况组
stAdr.psadr[8].btype = 9; // 进口油温度
stAdr.psadr[8].sadr = g_iec_conf.pstByqCode[i].uiOilTempEntry;
stAdr.psadr[9].group = 3; // 运行工况组
stAdr.psadr[9].btype = 10; // 出口油温度
stAdr.psadr[9].sadr = g_iec_conf.pstByqCode[i].uiOilTempOuter;
stAdr.psadr[10].group = 3; // 运行工况组
stAdr.psadr[10].btype = 11; // 油枕油位
stAdr.psadr[10].sadr = g_iec_conf.pstByqCode[i].uiOilPillowLevel;
stAdr.psadr[11].group = 3; // 运行工况组
stAdr.psadr[11].btype = 12; // 顶层油温度
stAdr.psadr[11].sadr = g_iec_conf.pstByqCode[i].uiOilTopTemp;
stAdr.psadr[12].group = 3; // 运行工况组
stAdr.psadr[12].btype = 13; // 绕组温度
stAdr.psadr[12].sadr = g_iec_conf.pstByqCode[i].uiWindingTemp;
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressEntry, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterPressOuter, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPosition, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTemperature, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempEntry, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiCoolWaterTempOuter, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressEntry, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPressOuter, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempEntry, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTempOuter, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilPillowLevel, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiOilTopTemp, &stAdr);
setSadrMatchRelations(g_iec_conf.pstByqCode[i].uiWindingTemp, &stAdr);
if (stAdr.psadr) free(stAdr.psadr);
stAdr.psadr = NULL;
}
for (i = 0; i < (int)g_iec_conf.iec_break_count; i++)
{
ST_SADR_MATCH stAdr;
memset(&stAdr, 0x00, sizeof(ST_SADR_MATCH));
stAdr.eqm_type = 2;
stAdr.count = 2;
stAdr.psadr = (ST_MATCH_LIST*)calloc(stAdr.count, sizeof(ST_MATCH_LIST));
stAdr.psadr[0].group = 4;
stAdr.psadr[0].btype = 1; // 断开电流
stAdr.psadr[0].sadr = g_iec_conf.pstBrkCode[i].uiAbortCurrent;
stAdr.psadr[1].group = 4;
stAdr.psadr[1].btype = 2; // 断开电压
stAdr.psadr[1].sadr = g_iec_conf.pstBrkCode[i].uiAbortVoltage;
setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortVoltage, &stAdr);
setSadrMatchRelations(g_iec_conf.pstBrkCode[i].uiAbortCurrent, &stAdr);
if (stAdr.psadr) free(stAdr.psadr);
stAdr.psadr = NULL;
}
return true;
}
// 打印IEC104配置参数
static void showIEC104Conf()
{
int i = 0;
vPrtLogMsg(LOG_DEBUG, RET_OK, "---> IEC104_CONF: iec_byq_count = %d, iec_break_count = %d", g_iec_conf.iec_byq_count, g_iec_conf.iec_break_count);
vPrtLogMsg(L

@ -0,0 +1,193 @@
/****************************************************************************
** File name : HTImageBusi.cpp
** Description : define memory data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
//#include "HTIEC104.h"
//#include "HTMemCacheData.h"
static const char *_FILE_ = "HTImageBusi.cpp";
/***************************************************************************
** function name : getImageThreshold
** deacription : get image define value
** parameter : none
** return code : NULL
***************************************************************************/
static void getImageThreshold(char *szSql)
{
int wstate = 0;
double value = 0.0f;
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) return;
MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
if (!res) return;
MYSQL_ROW row = NULL;
while (row = pdbHandle->GetRecord(res))
{
ST_IMG_THRESHOLD stThreshold;
string strKey = "";
memset(&stThreshold, 0x00, sizeof(ST_IMG_THRESHOLD));
memset(&stThreshold.value, 0xff, sizeof(double) * 3);
if (row[0] && strlen(row[0]) > 0) {
strncpy((char*)stThreshold.sensor_id, (const char*)row[0], sizeof(stThreshold.sensor_id));
strKey = row[0];
}
if (row[1] && strlen(row[1]) > 0) {
strncpy((char*)stThreshold.site_id, (const char*)row[1], sizeof(stThreshold.site_id));
}
if (row[2] && strlen(row[2]) > 0) {
stThreshold.phase = row[2][0];
}
if (row[3] && strlen(row[3]) > 0) {
strncpy((char*)stThreshold.desc, (const char*)row[3], sizeof(stThreshold.desc));
}
if (row[4] && strlen(row[4]) > 0) {
strncpy((char*)stThreshold.eqm_code, (const char*)row[4], sizeof(stThreshold.eqm_code));
}
//工作状态1 - 发电状态 2抽水状态 3空闲状态
if (row[5] && strlen(row[5]) > 0) {
wstate = atoi((const char*)row[5]);
}
if (row[6] && strlen(row[6]) > 0) {
value = atof((const char*)row[6]);
}
else value = HT_INVALID_VALUE;
if (row[7] && strlen(row[7]) > 0) {
stThreshold.eqm_type = (unsigned char)atoi((const char*)row[7]);
}
if (row[8] && strlen(row[8]) > 0) {
strncpy((char*)stThreshold.system_code, (const char*)row[8], sizeof(stThreshold.system_code));
}
map<string, ST_IMG_THRESHOLD>::iterator m_pIter;
mutex_lock(g_map_img_thres_mutex);
m_pIter = g_map_img_thres.find((char*)stThreshold.sensor_id);
if (m_pIter != g_map_img_thres.end())
{
switch (wstate)
{
case 1:
(m_pIter->second).value[0] = value;
break;
case 2:
(m_pIter->second).value[1] = value;
break;
case 3:
(m_pIter->second).value[2] = value;
break;
default:;
}
}
else {
if (wstate == 1) stThreshold.value[0] = value;
else if (wstate == 2) stThreshold.value[1] = value;
else if (wstate == 3) stThreshold.value[2] = value;
g_map_img_thres.insert(map<string, ST_IMG_THRESHOLD>::value_type(strKey, stThreshold));
}
mutex_unlock(g_map_img_thres_mutex);
}
pdbHandle->FreeRecord(res);
return;
}
// 加载图片阈值,包括变压器、GIS、避雷器三大主设备
void vLoadImageThreshold()
{
char szSql[DEF_BUFFER_1K+512] = { 0 };
// 加载变压器图片阈值
snprintf(szSql, sizeof(szSql), "SELECT sensor.sensor_code, sensor.site_id, sensor.position, sensor.position_des, tree.id AS m_eqm_code,"
"t.work_status, t.threshold, t.type, tree.system_code "
"FROM photo_threshold t, busi_site_tree tree, busi_transformer_sub_tree sub, busi_transformer_sensor sensor "
"WHERE t.main_tree_id = tree.id AND sub.equipment_id = tree.id AND t.sensor_code = sensor.sensor_code "
"AND sensor.equipment_id = sub.id and tree.status = '1'and sub.status = '1'and sensor.status = '1' "
"AND sub.equipment_type = '051' AND tree.equipment_type = '111' "
"ORDER BY sensor.sensor_code,t.work_status");
getImageThreshold(szSql);
// 加载GIS图片阈值
snprintf(szSql, sizeof(szSql), "SELECT sensor.sensor_code, sensor.site_id, sensor.position, sensor.position_des, tree.id AS m_eqm_code,"
"t.work_status, t.threshold, t.type, tree.system_code "
"FROM photo_threshold t, busi_site_tree tree, busi_gis_sub_tree sub, busi_gis_sensor sensor "
"WHERE t.main_tree_id = tree.id AND sub.equipment_id = tree.id AND t.sensor_code = sensor.sensor_code "
"AND sensor.equipment_id = sub.id and tree.status = '1'and sub.status = '1'and sensor.status = '1' "
"AND sub.equipment_type = '061' AND tree.equipment_type = '211' "
"ORDER BY sensor.sensor_code,t.work_status");
getImageThreshold(szSql);
// 加载避雷器图片阈值
snprintf(szSql, sizeof(szSql), "SELECT sensor.sensor_code, sensor.site_id, sensor.position, sensor.position_des, tree.id AS m_eqm_code,"
"t.work_status, t.threshold, t.type, tree.system_code "
"FROM photo_threshold t, busi_site_tree tree, busi_arrester_sub_tree sub, busi_arrester_sensor sensor "
"WHERE t.main_tree_id = tree.id AND sub.equipment_id = tree.id AND t.sensor_code = sensor.sensor_code "
"AND sensor.equipment_id = sub.id and tree.status = '1'and sub.status = '1'and sensor.status = '1' "
"AND sub.equipment_type = '051' AND tree.equipment_type = '411' "
"ORDER BY sensor.sensor_code,t.work_status");
getImageThreshold(szSql);
// 加载其他类图片阈值
snprintf(szSql, sizeof(szSql), "SELECT sensor.sensor_code, sensor.site_id, sensor.position, sensor.position_des, tree.id AS m_eqm_code,"
"t.work_status, t.threshold, t.type, tree.system_code "
"FROM photo_threshold t, busi_site_tree tree, busi_other_sub_tree sub, busi_other_sensor sensor "
"WHERE t.main_tree_id = tree.id AND sub.equipment_id = tree.id AND t.sensor_code = sensor.sensor_code "
"AND sensor.equipment_id = sub.id and tree.status = '1'and sub.status = '1'and sensor.status = '1' "
"AND sub.equipment_type = '031' AND tree.equipment_type = '511' "
"ORDER BY sensor.sensor_code,t.work_status");
getImageThreshold(szSql);
}
void vPrtImageThreshold(void)
{
map<string, ST_IMG_THRESHOLD>::iterator m_pIter;
m_pIter = g_map_img_thres.begin();
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print Image Threshold Tables----------");
vPrtLogMsg(LOG_DEBUG, RET_OK, "site_id\t\t\t\t eqm_code\t\t\t system_code\t T sensor_id value(1,2,3)");
while (m_pIter != g_map_img_thres.end())
{
vPrtLogMsg(LOG_DEBUG, RET_OK, "%-s %s %s %d %s [%.2f,%.2f,%.2f]",
(m_pIter->second).site_id, (m_pIter->second).eqm_code, (m_pIter->second).system_code,
(m_pIter->second).eqm_type, (m_pIter->second).sensor_id,
(m_pIter->second).value[0], (m_pIter->second).value[1], (m_pIter->second).value[2]);
m_pIter++;
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- Image_Threshold_size:%d-----------", g_map_img_thres.size());
return;
}
// 根据sensor_id获取阈值
bool getImageThresholdValuse(const char *sensor_id, ST_IMG_THRESHOLD &pstThresdhold)
{
map<string, ST_IMG_THRESHOLD>::iterator m_pIter;
double val = 0.0f;
mutex_lock(g_map_img_thres_mutex);
m_pIter = g_map_img_thres.find((char*)sensor_id);
if (m_pIter != g_map_img_thres.end())
{
memcpy(&pstThresdhold, &(m_pIter->second), sizeof(ST_IMG_THRESHOLD));
mutex_unlock(g_map_img_thres_mutex);
return true;
}
mutex_unlock(g_map_img_thres_mutex);
return false;
}

@ -0,0 +1,105 @@
/****************************************************************************
** File name : HTInitUtils.cpp
** Description : Defines service initialization API
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
#include "HTInitUtils.h"
static const char *_FILE_ = "HTInitUtils.cpp" ;
// make and get a globle seq number
int get_seqno(void)
{
int iseq = 0;
mutex_lock(g_seq_mutex);
iseq = ++g_seqno ;
if(g_seqno >= 255 )
g_seqno = 0;
mutex_unlock(g_seq_mutex);
return iseq;
}
int loadServiceEvent()
{
// 初始化日志共享资源锁
vInitLogMutex(); // 初始化log文件锁与句柄
mutex_create(g_seq_mutex);
mutex_create(g_IecCtrl_mutex);
mutex_create(g_map_byq_mutex);
//mutex_create(g_map_gis_mutex);
//mutex_create(g_map_blq_mutex);
//mutex_create(g_map_gis_104_mutex);
mutex_create(g_map_iec_mutex);
mutex_create(g_map_relation_mutex);
mutex_create(g_map_sadr_mutex);
mutex_create(g_map_img_thres_mutex);
mutex_create(g_map_work_mutex);
mutex_create(g_map_dev_time_stat_mutex);
mutex_create(g_map_gis_state_mutex);
memset(&g_IecCtrl, 0x00, sizeof(ST_IEC104_CTRL));
g_Running = 1 ; // 服务启动标志
g_TConfig.getIniConfig();
IEC104EnvLoad();
if(!CDBMySQL::Instance()->dbConnectPool()) {
vFreeLogMutex(); // 释放log文件锁与句柄
mutex_close(g_seq_mutex);
mutex_close(g_IecCtrl_mutex);
mutex_close(g_map_byq_mutex);
//mutex_close(g_map_gis_mutex);
//mutex_close(g_map_blq_mutex);
//mutex_close(g_map_gis_104_mutex);
mutex_close(g_map_iec_mutex);
mutex_close(g_map_relation_mutex);
mutex_close(g_map_sadr_mutex);
mutex_close(g_map_img_thres_mutex);
mutex_close(g_map_work_mutex);
mutex_close(g_map_dev_time_stat_mutex);
mutex_close(g_map_gis_state_mutex);
IEC104EnvFree();
g_Running = 0 ;
return RET_FAIL;
}
return RET_OK;
}
// 重新从数据库加载配置
void reloadServiceEvent(int platform_id)
{
//TDatabase* g_TDatabase = NULL;
//g_TDatabase = TDatabase::Instance();
}
int unLoadServiceEvent()
{
CDBMySQL::Instance()->dbFreeConnectPool();
g_Running = 0 ;
HTFreeThreadHandle();
// 释放日志共享资源锁
mutex_close(g_seq_mutex);
mutex_close(g_IecCtrl_mutex);
mutex_close(g_map_byq_mutex);
// mutex_close(g_map_gis_mutex);
// mutex_close(g_map_blq_mutex);
//mutex_close(g_map_gis_104_mutex);
mutex_close(g_map_iec_mutex);
mutex_close(g_map_relation_mutex);
mutex_close(g_map_sadr_mutex);
mutex_close(g_map_img_thres_mutex);
mutex_close(g_map_work_mutex);
mutex_close(g_map_dev_time_stat_mutex);
mutex_close(g_map_gis_state_mutex);
IEC104EnvFree();
return RET_OK;
}

@ -0,0 +1,283 @@
/****************************************************************************
** File name : FLTLogger.cpp
** Description : logger function define
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************
++++++++++ 64 ++++++++++
(1) windows os
printf("int_64 = %I64d\n", int64); -- 64
printf("int_64 = %I64u\n", int64); -- 64
(2) Linux os
printf("int_64 = %lld\n", int64); -- 64
printf("int_64 = %llu\n", int64); -- 64
****************************************************************************/
//#include "StdAfx.h"
#include "HTGlobal.h"
#include "HTPublic.h"
#include "HTLogger.h"
static const char *_FILE_="HTLogger.cpp";
static char g_logger_time[15] ; // 日志文件名称时间(YYYYMMDD)
/* mutex define */
static mutex mutex_Debug ; //跟踪日志
static FILE *g_fp;
/****************************************************************
** Description :
** param in : None
** :
** param out : None
** return code : None
****************************************************************/
void vInitLogMutex(void)
{
char szFile[DEF_BUFFER_256];
mutex_create(mutex_Debug);
// 创建日志文件并打开文件
memset(szFile, 0x00, sizeof(szFile)) ;
memset(g_logger_time, 0x00, sizeof(g_logger_time)); // 记录当前日志文件的时间(YYYYMMDD)
vGetHostTime(g_logger_time) ;
#ifdef _WIN32
sprintf(szFile,"%s\\debug%.8s.log", DEF_LOG_PATH_NAME,g_logger_time) ;
#else
sprintf(szFile,"%s/debug%.8s.log",DEF_LOG_PATH_NAME, g_logger_time) ;
#endif
if(iDirOrFileExist(DEF_LOG_PATH_NAME) != 0) {
//文件或目录不存在时, 创建文件或目录
if(iBuildDirent(DEF_LOG_PATH_NAME) != 0) {
printf("line:%d file:%s Create Directory:[%s] failed.\n",__LINE__,_FILE_, DEF_LOG_PATH_NAME);
return;
}
}
g_fp = fopen((const char*)szFile, (const char*)"a+");
if(NULL == g_fp) {
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__,_FILE_, szFile);
return;
}
if(iDirOrFileExist(DEF_RUN_INFO_PATH) != 0) {
//文件或目录不存在时, 创建文件或目录
if((iBuildDirent(DEF_RUN_INFO_PATH)) != 0) {
vPrtLogMsg(LOG_ERROR, errno, "Create Directory:[%s] failed,%s.", DEF_RUN_INFO_PATH,strerror(errno));
return;
}
}
}
/****************************************************************
** Description :
** param in : None
** :
** param out : None
** return code : None
****************************************************************/
void vFreeLogMutex(void)
{
mutex_close(mutex_Debug);
if(g_fp) fclose(g_fp);
}
/**********************************************************************
** Description :
** param in : iLine --
** : *szFileName --
** : *szErrMsg --
** : iCode --
** param out : None
** return code :
** : None
** : None
**********************************************************************/
void vPrtLogMsg(int line, const char *pszFileName, char logLevel, int iCode, /* const char *pszMsg,*/ ...)
{
char szTime[30],szFile[DEF_BUFFER_128]; // 128
char *p=NULL, szBuf[DEF_BUFFER_2K+1];
va_list vl ;
if(logLevel == __LOG_DEBUG ) {
if(g_TConfig.isLogDebug() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
else if(logLevel == __LOG_WARNG) {
if(g_TConfig.isLogWarning() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
else if(logLevel == __LOG_ERROR) {
if(g_TConfig.isLogError() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
if(g_fp == NULL) return ;
mutex_lock(mutex_Debug); //lock
//fseek(g_fp, 0l, SEEK_END) ;
vGetHostTime(szTime) ;
// if( ftell(g_fp) >= DEF_LOG_FILESZIE) { // 日志大小已经制定字节数时备份文件,并重新打开新文件
if( memcmp(szTime, g_logger_time, 8) != 0x00 ) { // 检查日志文件的时间是否为同一天,不是同一天时,重新产生新一天的日志文件名称
fclose(g_fp) ;
char szNFile[DEF_BUFFER_256];
memset(szNFile, 0x00, sizeof(szNFile)) ;
#ifdef _WIN32
sprintf(szNFile, "%s\\debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s\\debug%.8s.log", DEF_LOG_PATH_NAME,szTime) ;
#else
sprintf(szNFile, "%s/debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s/debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#endif
rename(szFile, szNFile) ;
if((g_fp = fopen(szFile,"a+")) == NULL) {
mutex_unlock(mutex_Debug); //unlock
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__,_FILE_, szFile);
return ;
}
strncpy(g_logger_time, szTime, 14); // 记录最近一次变更过的时间(YYYYMMDD)
}
memset(szTime,0,sizeof(szTime)) ;
memset(szBuf, 0x00, sizeof(szBuf));
vGetHostTimeFmt(szTime);
if(logLevel == __LOG_DEBUG) { // 跟踪日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [DEBUG]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [DEBUG]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
else if(logLevel == __LOG_WARNG) { // 告警日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [WARNING]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [WARNING]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
else if(logLevel == __LOG_ERROR) { // 错误日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [ERROR]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [ERROR]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s ", szBuf) ;
}
va_start(vl, iCode);
while((p = va_arg(vl, char *))) {
#ifdef _WIN32
_vsnprintf(szBuf, sizeof(szBuf), p, vl);
#else
vsnprintf(szBuf, sizeof(szBuf), p, vl);
#endif
break;
}
va_end(vl);
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s\n", szBuf) ;
}
fprintf(g_fp,"%s\n",szBuf);
fflush(g_fp);
mutex_unlock(mutex_Debug); //unlock
}
/*************************************************************************
** Description : (16)
** param in : iLine -- ,
** : *szFileName --
** : *pszTitle --
** : *pusMsg --
** : uiMsgLen --
** param out : None
** return code : None
************************************************************************/
void vPrtLogHex(int line, const char *pszFileName,char logLevel, int sockid, /* unsigned short msg_id, */
const char pszMsgType, unsigned char *pusMsg,int uiMsgLen)
{
int i, j;
char szBuf1[80+1], szBuf2[80+1];
char szTime[20+1], szHex[3+1];
char szFile[DEF_BUFFER_256];
char szTitle[1024]={0};
if(g_TConfig.isLogPack() == 0x00) return ;
if(g_fp == NULL) return ;
mutex_lock(mutex_Debug); //lock
//fseek(g_fp, 0l, SEEK_END) ;
vGetHostTime(szTime) ;
if( memcmp(szTime, g_logger_time, 8) != 0x00) { // 检查日志文件的时间是否为同一天,不是同一天时,重新产生新一天的日志文件名称
// if(ftell(g_fp) >= DEF_LOG_FILESZIE) {
fclose(g_fp) ;
char szNFile[DEF_BUFFER_256];
memset(szNFile, 0x00, sizeof(szNFile)) ;
#ifdef _WIN32
sprintf(szNFile, "%s\\debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s\\debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#else
sprintf(szNFile, "%s/debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s/debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#endif
rename(szFile, szNFile) ;
if((g_fp = fopen(szFile,"a+")) == NULL) {
mutex_unlock(mutex_Debug); //unlock
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__, _FILE_, szFile);
return ;
}
strncpy(g_logger_time, szTime,14); // 记录最近一次变更过的时间(YYYYMMDD)
}
vGetHostTimeFmt( szTime ) ; /* 获取系统时间 */
if(pszMsgType == PRT_PACK_SEND) {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [SendData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [SendData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
else if(pszMsgType == PRT_PACK_RECV) {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [RecvData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [RecvData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
else {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [PrntData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [PrntData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s", szTitle);
}
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s", szTime,GETTID(),line,pszFileName) ;
for(i=0; i<uiMsgLen; i+=16, pusMsg+=16)
{
memset(szBuf1, 0, sizeof(szBuf1));
sprintf(szBuf1, "%04XH ",i);
memset(szBuf2, 0, sizeof(szBuf2));
for(j=0; j<16; j++)
{
if( (uiMsgLen-i) < 16 && j >= (uiMsgLen%16) )
break;
sprintf(szHex, "%02X ", pusMsg[j]&0xFF);
strcat(szBuf1, szHex);
if(j==7)
strcat(szBuf1, " ");
if(pusMsg[j]>0x20 && pusMsg[j]<0x0ff)
szBuf2[j] = pusMsg[j];
else
szBuf2[j] = '_';
}
for(; j<16; j++)
{
if(j==7)
strcat(szBuf1, " ");
strcat(szBuf1, " ");
}
fprintf(g_fp, "%s --> %s %s\n", szTitle, szBuf1, szBuf2);
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s --> %s %s\n", szTitle, szBuf1, szBuf2);
}
}
fflush(g_fp); // 写入文件
mutex_unlock(mutex_Debug); //unlock
}

@ -0,0 +1,794 @@
/****************************************************************************
** File name : HTMemCacheData.cpp
** Description : define memory data struct
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
#include "HTIEC104.h"
#include "HTMemCacheData.h"
static const char *_FILE_ = "HTMemData.cpp";
/***************************************************************************
** function name : vLoadBYQThresholdTable
** deacription : get byq define value & site_id-->site_code relation.
** parameter : none
** return code : NULL
***************************************************************************/
static void vLoadBYQThresholdTable(bool is_load)
{
char szSql[1024] = { 0 };
int wstate = 0;
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) return;
snprintf(szSql, sizeof(szSql), "select t1.name,t1.site_id,t1.system_code,t.main_tree_id,t.work_status,"
"t.coolingwater_inlet_pressure, t.coolingwater_outlet_pressure, t.coolingwater_inlet_temperature, t.coolingwater_outlet_temperature,"
"t.circulating_oil_inlet_pressure,t.circulating_oil_outlet_pressure, t.winding_temperature, t.oilpillow_oillevel, t.transformer_Ontology_oillevel,"
"t.oil_temperature, t.top_oil_temperature,t.circulating_oil_inlet_temperature,t.circulating_oil_out_temperature "
"from busi_site_tree t1, transformer_runing_status_threshold t "
"where t1.id = t.main_tree_id and t1.status = '1' and t1.site_id = t.site_id "
"order BY t1.system_code");
MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
if (!res) return;
MYSQL_ROW row = NULL;
while (row = pdbHandle->GetRecord(res))
{
ST_BYQ_RUN_STATE_THRESHOLD stByq;
int idx = 0;
ST_STAT_THRESHOLD stThreshold;
string strKey = "";
memset(&stByq, 0x00, sizeof(ST_BYQ_RUN_STATE_THRESHOLD));
memset(&stThreshold, 0x00, sizeof(ST_STAT_THRESHOLD));
if (row[0] && strlen(row[0]) > 0) {
strncpy((char*)stByq.dev_name, (const char*)row[0], sizeof(stByq.dev_name));
}
if (row[1] && strlen(row[1]) > 0) {
strncpy((char*)stByq.site_id, (const char*)row[1], sizeof(stByq.site_id));
}
if (row[2] && strlen(row[2]) > 0) {
strncpy((char*)stByq.system_code, (const char*)row[2], sizeof(stByq.system_code));
//strKey = (char*)stByq.system_code;
}
if (row[3] && strlen(row[3]) > 0) {
strncpy((char*)stByq.eqm_code, (const char*)row[3], sizeof(stByq.eqm_code)); // main_tree_id源自表busi_site_tree.id
strKey = (char*)stByq.eqm_code;
}
//工作状态1 - 发电状态 2抽水状态 3空闲状态
if (row[4] && strlen(row[4]) > 0) {
wstate = atoi((const char*)row[4]);
}
//stThreshold.wstate = wstate;
if (row[5] && strlen(row[5]) > 0) {
strcpy(stThreshold.stField[idx].field, "coolingwater_inlet_pressure");
stThreshold.stField[idx++].value = atof((const char*)row[5]); // 冷却水进口压力
}
else {
strcpy(stThreshold.stField[idx].field, "coolingwater_inlet_pressure");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 冷却水进口压力
}
if (row[6] && strlen(row[6]) > 0) {
strcpy(stThreshold.stField[idx].field, "coolingwater_outlet_pressure");
stThreshold.stField[idx++].value = atof((const char*)row[6]); // 冷却水出口压力
}
else {
strcpy(stThreshold.stField[idx].field, "coolingwater_outlet_pressure");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 冷却水出口压力
}
if (row[7] && strlen(row[7]) > 0) {
strcpy(stThreshold.stField[idx].field, "coolingwater_inlet_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[7]); // 冷却水进口温度
}
else {
strcpy(stThreshold.stField[idx].field, "coolingwater_inlet_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 冷却水进口温度
}
if (row[8] && strlen(row[8]) > 0) {
strcpy(stThreshold.stField[idx].field, "coolingwater_outlet_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[8]); // 冷却水出口温度
}
else {
strcpy(stThreshold.stField[idx].field, "coolingwater_outlet_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 冷却水出口温度
}
if (row[9] && strlen(row[9]) > 0) {
strcpy(stThreshold.stField[idx].field, "circulating_oil_inlet_pressure");
stThreshold.stField[idx++].value = atof((const char*)row[9]); // 循环油进口压力
}
else {
strcpy(stThreshold.stField[idx].field, "circulating_oil_inlet_pressure");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 循环油进口压力
}
if (row[10] && strlen(row[10]) > 0) {
strcpy(stThreshold.stField[idx].field, "circulating_oil_outlet_pressure");
stThreshold.stField[idx++].value = atof((const char*)row[10]); // 循环油出口压力
}
else {
strcpy(stThreshold.stField[idx].field, "circulating_oil_outlet_pressure");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 循环油出口压力
}
if (row[11] && strlen(row[11]) > 0) {
strcpy(stThreshold.stField[idx].field, "winding_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[11]); // 绕组温度
}
else {
strcpy(stThreshold.stField[idx].field, "winding_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 绕组温度
}
if (row[12] && strlen(row[12]) > 0) {
strcpy(stThreshold.stField[idx].field, "oilpillow_oillevel");
stThreshold.stField[idx++].value = atof((const char*)row[12]); // 油枕油位
}
else {
strcpy(stThreshold.stField[idx].field, "oilpillow_oillevel");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 油枕油位
}
if (row[13] && strlen(row[13]) > 0) {
strcpy(stThreshold.stField[idx].field, "transformer_Ontology_oillevel");
stThreshold.stField[idx++].value = atof((const char*)row[13]); // 变压器本体油位
}
else {
strcpy(stThreshold.stField[idx].field, "transformer_Ontology_oillevel");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 变压器本体油位
}
if (row[14] && strlen(row[14]) > 0) {
strcpy(stThreshold.stField[idx].field, "oil_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[14]); // 变压器本体油温
}
else {
strcpy(stThreshold.stField[idx].field, "oil_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 变压器本体油温
}
if (row[15] && strlen(row[15]) > 0) {
strcpy(stThreshold.stField[idx].field, "top_oil_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[15]); // 顶层油温
}
else {
strcpy(stThreshold.stField[idx].field, "top_oil_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 顶层油温
}
if (row[16] && strlen(row[16]) > 0) {
strcpy(stThreshold.stField[idx].field, "circulating_oil_inlet_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[16]); // 变压器油进口油温度(℃)
}
else {
strcpy(stThreshold.stField[idx].field, "circulating_oil_inlet_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 变压器油进口油温度(℃)
}
if (row[17] && strlen(row[17]) > 0) {
strcpy(stThreshold.stField[idx].field, "circulating_oil_out_temperature");
stThreshold.stField[idx++].value = atof((const char*)row[17]); // 变压器油出口油温度(℃)
}
else {
strcpy(stThreshold.stField[idx].field, "circulating_oil_out_temperature");
stThreshold.stField[idx++].value = HT_INVALID_VALUE; // 变压器油出口油温度(℃)
}
stThreshold.fnum = idx;
if (idx >= MAX_RUN_STATUS_COUNT) {
vPrtLogMsg(LOG_WARNG, RET_OK, "Onec devices max threshold count:%d, current count:%d", MAX_RUN_STATUS_COUNT,idx);
stThreshold.fnum = MAX_RUN_STATUS_COUNT - 1;
}
map<string, ST_BYQ_RUN_STATE_THRESHOLD>::iterator m_pIter;
mutex_lock(g_map_byq_mutex);
m_pIter = g_map_thres_byq.find((char*)stByq.eqm_code);
if (m_pIter != g_map_thres_byq.end())
{
switch (wstate)
{
case 1:
memcpy(&(m_pIter->second).stThreashod[0], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
case 2:
memcpy(&(m_pIter->second).stThreashod[1], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
case 3:
memcpy(&(m_pIter->second).stThreashod[2], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
default:;
}
}
else {
switch (wstate)
{
case 1:
memcpy(&stByq.stThreashod[0], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
case 2:
memcpy(&stByq.stThreashod[1], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
case 3:
memcpy(&stByq.stThreashod[2], &stThreshold, sizeof(ST_STAT_THRESHOLD));
break;
default:;
}
g_map_thres_byq.insert(map<string, ST_BYQ_RUN_STATE_THRESHOLD>::value_type(strKey, stByq));
}
mutex_unlock(g_map_byq_mutex);
}
pdbHandle->FreeRecord(res);
return;
}
static void vPrtBYQThresholdTable(void)
{
map<string, ST_BYQ_RUN_STATE_THRESHOLD>::iterator m_pIter;
m_pIter = g_map_thres_byq.begin();
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print BYQ Threshold Tables----------");
vPrtLogMsg(LOG_DEBUG, RET_OK, "site_id\t\t\t\t eqm_code\t\t\t system_code\t ST dev_name");
while (m_pIter != g_map_thres_byq.end())
{
vPrtLogMsg(LOG_DEBUG, RET_OK, "%-s %s %s %c %s",
(m_pIter->second).site_id, (m_pIter->second).eqm_code, (m_pIter->second).system_code,
((m_pIter->second).wstate == 0 ? 0x2f : 0x30+(m_pIter->second).wstate), (m_pIter->second).dev_name);
m_pIter++;
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- BYQ_Threshold_size:%d-----------", g_map_thres_byq.size());
return;
}
// 根据运行工况的字典名称,获取阈值
double getThresholdValuse(const char *eqm_code, const char *pFiledName, int jobState)
{
ST_BYQ_RUN_STATE_THRESHOLD stByq;
map<string, ST_BYQ_RUN_STATE_THRESHOLD>::iterator m_pIter;
double val = 0.0f;
if (jobState <= 0) {
vPrtLogMsg(LOG_WARNG, RET_FAIL, "Check Device Statue:%d(invalid)", jobState);
return val;
}
mutex_lock(g_map_byq_mutex);
m_pIter = g_map_thres_byq.find((char*)eqm_code);
if (m_pIter == g_map_thres_byq.end())
{
mutex_unlock(g_map_byq_mutex);
return val;
}
memcpy(&stByq, &m_pIter->second, sizeof(ST_BYQ_RUN_STATE_THRESHOLD));
mutex_unlock(g_map_byq_mutex);
int i = 0;
while (i < stByq.stThreashod[jobState-1].fnum)
{
if (stringncasecmp( (const char*)stByq.stThreashod[jobState-1].stField[i].field, (const char*)pFiledName, strlen((const char*)pFiledName)) == 0)
{
return stByq.stThreashod[jobState - 1].stField[i].value == HT_INVALID_VALUE ? 0 : stByq.stThreashod[jobState - 1].stField[i].value;
}
i++;
}
return val;
}
//加载IEC104点表数据
static void vLoadIECPointTable()
{
char szSql[512] = { 0 };
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) return;
snprintf(szSql, sizeof(szSql), "select p.site_id, p.site_tree_id, p.stype, p.sadr, p.sno,p.isget,p.unit,"
"p.sysunit,p.devrate,p.thresholdfield,p.desct,"
"SUBSTR(t.equipment_type from 1 for 1) as eqm_type,p.warnflag,t.system_code "
"from iec_points_conf p, busi_site_tree t "
"where p.sadr > 0 and p.state ='1' and t.id=p.site_tree_id and t.status='1' "
"ORDER BY p.site_id, p.site_tree_id, p.sadr");
MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
if (!res) return;
MYSQL_ROW row = NULL;
while (row = pdbHandle->GetRecord(res))
{
ST_IECPOINT_TABLE stPoint;
ST_DEVICE_TIME_STAT stDevStat;
memset(&stPoint, 0x00, sizeof(ST_IECPOINT_TABLE));
memset(&stDevStat, 0x00, sizeof(ST_DEVICE_TIME_STAT));
if (row[0] && strlen(row[0]) > 0)
{
strncpy((char*)stPoint.site_id, (const char*)row[0], sizeof(stPoint.site_id));
}
if (row[1] && strlen(row[1]) > 0) {
strncpy((char*)stPoint.eqm_code, (const char*)row[1], sizeof(stPoint.eqm_code));
}
if (row[2] && strlen(row[2]) > 0) {
stPoint.stype = atoi(row[2]);
}
if (row[3] && strlen(row[3]) > 0) {
stPoint.sadr = atoi(row[3]);
}
if (row[4] && strlen(row[4]) > 0) {
stPoint.sno = atoi(row[4]);
}
if (row[5] && strlen(row[5]) > 0) {
stPoint.isget = (unsigned char)atoi(row[5]);
}
if (row[6] && strlen(row[6]) > 0) {
stPoint.unit = (unsigned short)atoi(row[6]);
}
if (row[7] && strlen(row[7]) > 0) {
stPoint.sysunit = (unsigned short)atoi(row[7]);
}
if (row[8] && strlen(row[8]) > 0) {
stPoint.devrate = atof(row[8]);
}
if (row[9] && strlen(row[9]) > 0) {
strncpy((char*)stPoint.fieldname, row[9], sizeof(stPoint.fieldname));
}
if (row[10] && strlen(row[10]) > 0) {
strncpy((char*)stPoint.poidesc, row[10], sizeof(stPoint.poidesc));
strncpy((char*)stDevStat.desct, row[10], sizeof(stDevStat.desct));
}
if (row[11] && strlen(row[11]) > 0) {
stPoint.eqm_type = (unsigned char)atoi(row[11]);
}
if (row[12] && strlen(row[12]) > 0) {
stPoint.warnFlag = (unsigned char)atoi(row[12]);
}
if (row[13] && strlen(row[13]) > 0) {
strncpy((char*)stPoint.sys_code, (const char*)row[13], sizeof(stPoint.sys_code));
strncpy((char*)stDevStat.sys_code, (const char*)row[13], sizeof(stDevStat.sys_code));
}
mutex_lock(g_map_iec_mutex);
map<unsigned int, ST_IECPOINT_TABLE>::iterator m_pIter;
m_pIter = g_map_iec.find(stPoint.sadr);
if (m_pIter == g_map_iec.end())
{
stPoint.bfault = 0; // 初始状态0,无事故
stPoint.wstate = 3; // 默认为空闲状态
g_map_iec.insert(map<unsigned int, ST_IECPOINT_TABLE>::value_type(stPoint.sadr, stPoint));
}
else {
// 保留原数据
stPoint.bfault = (m_pIter->second).bfault;
stPoint.wstate = (((m_pIter->second).wstate) & 0xff);
stPoint.cval = (((m_pIter->second).cval) & 0xff);
stPoint.fval = (m_pIter->second).fval;
stPoint.dtime = (m_pIter->second).dtime;
//覆盖更新数据
memcpy(&(m_pIter->second), &stPoint, sizeof(ST_IECPOINT_TABLE));
}
mutex_unlock(g_map_iec_mutex);
if (stPoint.eqm_type == 1) {
mutex_lock(g_map_dev_time_stat_mutex);
map<string, ST_DEVICE_TIME_STAT>::iterator m_pIters;
m_pIters = g_map_dev_time_stat.find((char*)stDevStat.sys_code);
if (m_pIters == g_map_dev_time_stat.end())
{
stDevStat.usTime = time(NULL); // 初始时间
stDevStat.wstate = 3; // 默认为空闲状态
g_map_dev_time_stat.insert(map<string, ST_DEVICE_TIME_STAT>::value_type((char*)stDevStat.sys_code, stDevStat));
}
mutex_unlock(g_map_dev_time_stat_mutex);
}
}
pdbHandle->FreeRecord(res);
return;
}
// 刷新设备更新时间
void SethDevTimeStat(unsigned char *sys_code, unsigned char ws)
{
mutex_lock(g_map_dev_time_stat_mutex);
map<string, ST_DEVICE_TIME_STAT>::iterator m_pIters;
m_pIters = g_map_dev_time_stat.find((char*)sys_code);
if (m_pIters != g_map_dev_time_stat.end())
{
//(m_pIters->second).usTime = time(NULL);
(m_pIters->second).wstate = ws; // 默认为空闲状态
}
mutex_unlock(g_map_dev_time_stat_mutex);
}
// 获取状态时间
time_t GetDevTimeStat(unsigned char *sys_code, unsigned char *ws)
{
time_t usTime = 0;
mutex_lock(g_map_dev_time_stat_mutex);
map<string, ST_DEVICE_TIME_STAT>::iterator m_pIters;
m_pIters = g_map_dev_time_stat.find((char*)sys_code);
if (m_pIters != g_map_dev_time_stat.end())
{
if ((m_pIters->second).usTime == 0) {
(m_pIters->second).usTime = time(NULL); // 初始时间
}
else {
usTime = (m_pIters->second).usTime;
(m_pIters->second).usTime = time(NULL)+1;
}
if ((m_pIters->second).wstate == 0) {
(m_pIters->second).wstate = 3; // 默认为空闲状态
}
*ws = (m_pIters->second).wstate ;
}
mutex_unlock(g_map_dev_time_stat_mutex);
return usTime;
}
// 打印时间
void vPrtTimeStat()
{
char sTime[32] = { 0 };
map<string, ST_DEVICE_TIME_STAT>::iterator m_pIter;
mutex_lock(g_map_dev_time_stat_mutex);
m_pIter = g_map_dev_time_stat.begin();
vPrtLogMsg(LOG_WARNG, RET_OK, "---------Print time and state Table Config----------");
vPrtLogMsg(LOG_WARNG, RET_OK, " sys_code\t\t\t time \t\t stat \t desc");
while (m_pIter != g_map_dev_time_stat.end())
{
vTranHostTimeFmt((m_pIter->second).usTime, sTime);
vPrtLogMsg(LOG_WARNG, RET_OK, "--> %s %s %c %s", (m_pIter->second).sys_code,
sTime, ((m_pIter->second).wstate + 0x30), (m_pIter->second).desct);
m_pIter++;
}
vPrtLogMsg(LOG_WARNG, RET_OK, "---------- Point time and state :%d-----------", g_map_dev_time_stat.size());
mutex_unlock(g_map_dev_time_stat_mutex);
return;
}
// 打印点表配置信息
static void vPrtIECPointTable()
{
map<unsigned int, ST_IECPOINT_TABLE>::iterator m_pIter;
mutex_lock(g_map_iec_mutex);
m_pIter = g_map_iec.begin();
vPrtLogMsg(LOG_WARNG, RET_OK, "---------Print IEC104 Point Table Config Relation----------");
vPrtLogMsg(LOG_WARNG, RET_OK, "sys_code\t\t\t\t\tsadr\t\t value G rate(%%) EQM_T desc");
while (m_pIter != g_map_iec.end())
{
//vPrtLogMsg(LOG_WARNG, RET_OK, "--> %s %s %05d(0x%04x) %03d %.4f %c %.2f %d %s", (m_pIter->second).sys_code,
vPrtLogMsg(LOG_WARNG, RET_OK, "--> %s %s %05d(0x%04x) %.4f %c %.2f %d %s", (m_pIter->second).sys_code,
((m_pIter->second).stype == 1 ? "YX" : "YC"),
(m_pIter->second).sadr, (m_pIter->second).sadr,
// (m_pIter->second).sno,
((m_pIter->second).stype == 1) ? ((m_pIter->second).cval & 0xff) : (m_pIter->second).fval,
((m_pIter->second).isget == 0 ? 0x2f : (m_pIter->second).isget+0x30), (m_pIter->second).devrate,
(m_pIter->second).eqm_type, (m_pIter->second).poidesc);
m_pIter++;
}
vPrtLogMsg(LOG_WARNG, RET_OK, "---------- Point Table_size:%d-----------", g_map_iec.size());
mutex_unlock(g_map_iec_mutex);
return;
}
//加载主变设备ID列表,用于缓存主变设备工作状态,1:发电 2:抽水 3:空闲
static void vLoadByqDeviceStateTable()
{
char szSql[512] = { 0 };
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) return;
snprintf(szSql, sizeof(szSql), "select site_id,id,name from busi_site_tree t where equipment_type='111' and status='1' ORDER BY name");
MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
if (!res) return;
string strKey = "";
MYSQL_ROW row = NULL;
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
while (row = pdbHandle->GetRecord(res))
{
ST_BYQWORK_STATUS stWstate;
memset(&stWstate, 0x00, sizeof(ST_BYQWORK_STATUS));
if (row[0] && strlen(row[0]) > 0)
{
strncpy((char*)stWstate.site_id, (const char*)row[0], sizeof(stWstate.site_id));
}
if (row[1] && strlen(row[1]) > 0)
{
strncpy((char*)stWstate.eqm_code, (const char*)row[1], sizeof(stWstate.eqm_code));
strKey = row[1];
}
if (row[2] && strlen(row[2]) > 0) {
strncpy((char*)stWstate.eqm_name, (const char*)row[2], sizeof(stWstate.eqm_name));
}
mutex_lock(g_map_work_mutex);
bool isAdd = false;
m_pIter = g_map_work.find(strKey);
if (m_pIter != g_map_work.end())
{
strcpy((char*)(m_pIter->second).site_id, (const char*)stWstate.site_id);
strcpy((char*)(m_pIter->second).eqm_code, (const char*)stWstate.eqm_code);
strcpy((char*)(m_pIter->second).eqm_name, (const char*)stWstate.eqm_name);
}
else{
stWstate.bfault = 0;
stWstate.wstate = 3;
g_map_work.insert(map<string, ST_BYQWORK_STATUS>::value_type(strKey, stWstate));
}
mutex_unlock(g_map_work_mutex);
}
pdbHandle->FreeRecord(res);
return;
}
// 打印变压器工作状态
static void vPrtByqDeviceStateTable()
{
int i = 0;
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
mutex_lock(g_map_work_mutex);
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print byq work state Table ----------");
vPrtLogMsg(LOG_DEBUG, RET_OK, " index site_id\t\t\t\t eqm_code\t\t\t wstate\t fault\teqm_name");
m_pIter = g_map_work.begin();
while (m_pIter != g_map_work.end())
{
vPrtLogMsg(LOG_DEBUG, RET_OK, "--> %d %s %s %d %s %s", i + 1,
(m_pIter->second).site_id,
(m_pIter->second).eqm_code,
(m_pIter->second).wstate,
((m_pIter->second).bfault == 0 ? "Normal" : "Fault"),
(m_pIter->second).eqm_name); //0:分 1 : 合
m_pIter++; i++;
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- Print byq work state, size:%d-----------", g_map_work.size());
mutex_unlock(g_map_work_mutex);
return;
}
// 设置主变工作状态
void vSetByqDeviceState(unsigned char *pszEqm_code, unsigned char state)
{
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
mutex_lock(g_map_work_mutex);
m_pIter = g_map_work.find((char*)pszEqm_code);
if (m_pIter != g_map_work.end())
{
(m_pIter->second).wstate = state;
}
mutex_unlock(g_map_work_mutex);
}
// 获取工作状态
unsigned char cGetByqDeviceState(unsigned char *pszEqm_code)
{
unsigned char state = 3;
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
mutex_lock(g_map_work_mutex);
m_pIter = g_map_work.find((char*)pszEqm_code);
if (m_pIter != g_map_work.end())
{
state = ((m_pIter->second).wstate & 0xff);
}
mutex_unlock(g_map_work_mutex);
return state;
}
// 设置主变事故状态
void vSetByqDeviceFaultState(unsigned char *pszEqm_code, unsigned char state)
{
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
mutex_lock(g_map_work_mutex);
m_pIter = g_map_work.find((char*)pszEqm_code);
if (m_pIter != g_map_work.end())
{
(m_pIter->second).bfault = state;
}
mutex_unlock(g_map_work_mutex);
}
// 获取主变事故状态
unsigned char cGetByqDeviceFaultState(unsigned char *pszEqm_code)
{
unsigned char state = 3;
map<string, ST_BYQWORK_STATUS>::iterator m_pIter;
mutex_lock(g_map_work_mutex);
m_pIter = g_map_work.find((char*)pszEqm_code);
if (m_pIter != g_map_work.end())
{
state = ((m_pIter->second).bfault & 0xff);
}
mutex_unlock(g_map_work_mutex);
return state;
}
//加载设备关系表
static void vLoadDeviceRelationsTable()
{
char szSql[512] = { 0 };
CDBMySQL *pdbHandle = CDBMySQL::Instance();
if (!pdbHandle) return;
snprintf(szSql, sizeof(szSql), "select t.site_id,b.transformer_id, b.equipment_id,SUBSTR(t.equipment_type from 1 for 1) as eqm_type, "
"t.system_code "
"from busi_equipment_relationship b, busi_site_tree t "
"where t.status = '1' and b.equipment_id = t.id "
"ORDER BY t.site_id"); //,b.transformer_id
MYSQL_RES *res = pdbHandle->SelectRecord(szSql);
if (!res) return;
string strKey = "";
MYSQL_ROW row = NULL;
multimap<string, ST_DEV_RELATION>::iterator m_pIter;
while (row = pdbHandle->GetRecord(res))
{
ST_DEV_RELATION stRelation;
memset(&stRelation, 0x00, sizeof(ST_DEV_RELATION));
if (row[0] && strlen(row[0]) > 0)
{
strncpy((char*)stRelation.site_id, (const char*)row[0], sizeof(stRelation.site_id));
}
if (row[1] && strlen(row[1]) > 0)
{
strncpy((char*)stRelation.m_eqm_code, (const char*)row[1], sizeof(stRelation.m_eqm_code));
}
if (row[2] && strlen(row[2]) > 0) {
strncpy((char*)stRelation.s_eqm_code, (const char*)row[2], sizeof(stRelation.s_eqm_code));
strKey = row[2];
}
if (row[3] && strlen(row[3]) > 0) {
stRelation.s_eqm_type = atoi((const char*)row[3]);
}
if (row[4] && strlen(row[4]) > 0) {
strncpy((char*)stRelation.s_sys_code, (const char*)row[4], sizeof(stRelation.s_sys_code));
}
stRelation.bClose = 1;
stRelation.bfault = 0;
stRelation.wstate = 3;
mutex_lock(g_map_relation_mutex);
bool isAdd = false;
m_pIter = g_map_relation.find(strKey);
if (m_pIter != g_map_relation.end())
{
for (int k = 0; k != (int)g_map_relation.count(strKey); k++, m_pIter++)
{
if ((0 == stringncasecmp((const char*)stRelation.site_id,(const char*)((m_pIter->second).site_id),strlen((const char*)(m_pIter->second).site_id))) &&
(0 == stringncasecmp((const char*)stRelation.m_eqm_code, (const char*)((m_pIter->second).m_eqm_code), strlen((const char*)(m_pIter->second).m_eqm_code))))
{
isAdd = true;
break;
}
}
if (!isAdd) {
g_map_relation.insert(multimap<string, ST_DEV_RELATION>::value_type(strKey, stRelation));
}
}
else g_map_relation.insert(multimap<string, ST_DEV_RELATION>::value_type(strKey, stRelation));
mutex_unlock(g_map_relation_mutex);
}
pdbHandle->FreeRecord(res);
return;
}
// 打印设备关系表
static void vPrtDeviceRelationsTable()
{
int i = 0;
multimap<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------Print device Relations Table Config ----------");
vPrtLogMsg(LOG_DEBUG, RET_OK, " index m_eqm_code\t\t\ts_eqm_code\t\t\t sType wstate\tfault\tclose\t");
m_pIter = g_map_relation.begin();
while (m_pIter != g_map_relation.end())
{
vPrtLogMsg(LOG_DEBUG, RET_OK, "--> %d %s %s %d \t%d\t%s\t%s", i + 1,
// (m_pIter->second).site_id,
(m_pIter->second).m_eqm_code,
(m_pIter->second).s_sys_code,
(m_pIter->second).s_eqm_type,
(m_pIter->second).wstate,
((m_pIter->second).bfault == 0 ? "Normal" : "Fault"),
((m_pIter->second).bClose == 0 ? "Opend" : "Close")); //0:分 1 : 合
m_pIter++; i++;
}
vPrtLogMsg(LOG_DEBUG, RET_OK, "---------- Point Print device Relations_size:%d-----------", g_map_relation.size());
mutex_unlock(g_map_relation_mutex);
return;
//方式1
/*int k;
multimap<string, int>::iterator m;
m = m_map.find(s);
for (k = 0; k != m_map.count(s); k++, m++)
cout << m->first << "--" << m->second << endl;
*/
}
// 根据s_eqm_code获取对应的主变设备编码
bool bGetMasterEqmCodeBySubEqmCode(unsigned char *site_id, unsigned char *s_eqm_code, unsigned char *m_eqm_code)
{
bool isFind = false;
multimap<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
m_pIter = g_map_relation.find((char*)s_eqm_code);
if (m_pIter != g_map_relation.end())
{
for (int c = 0; c < (int)g_map_relation.count((const char*)s_eqm_code); c++, m_pIter++)
{
if (0 != stringncasecmp(
(const char*)site_id,
(const char*)((m_pIter->second).site_id),
strlen((const char*)(m_pIter->second).site_id))) continue;
strcpy((char*)m_eqm_code, (const char*)((m_pIter->second).m_eqm_code));
isFind = true;
break;
}
}
mutex_unlock(g_map_relation_mutex);
return isFind;
}
// 设置运行状态
void flushDevWorkState(unsigned char *site_id, unsigned char *m_eqm_code, unsigned char state)
{
map<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
for (m_pIter = g_map_relation.begin(); m_pIter != g_map_relation.end(); m_pIter++)
{
if (0 != stringncasecmp(
(const char*)site_id,
(const char*)((m_pIter->second).site_id),
strlen((const char*)(m_pIter->second).site_id))) continue;
if (0 != stringncasecmp(
(const char*)m_eqm_code,
(const char*)((m_pIter->second).m_eqm_code),
strlen((const char*)(m_pIter->second).m_eqm_code))) continue;
(m_pIter->second).wstate = state;
}
mutex_unlock(g_map_relation_mutex);
return ;
}
//设备机组事故状态 state=false:正常 true:事故
bool flushFaultState(unsigned char *site_id, unsigned char *m_eqm_code, unsigned char state)
{
map<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
for (m_pIter = g_map_relation.begin(); m_pIter != g_map_relation.end(); m_pIter++)
{
if (0 != stringncasecmp(
(const char*)site_id,
(const char*)((m_pIter->second).site_id),
strlen((const char*)(m_pIter->second).site_id))) continue;
if (0 != stringncasecmp(
(const char*)m_eqm_code,
(const char*)((m_pIter->second).m_eqm_code),
strlen((const char*)(m_pIter->second).m_eqm_code))) continue;
(m_pIter->second).bfault = state;
}
mutex_unlock(g_map_relation_mutex);
return true;
}
// 刷新GIS的开关状态
bool flushDevCloseState(unsigned char *site_id, unsigned char *s_eqm_code, unsigned char state)
{
map<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
m_pIter = g_map_relation.find((char*)s_eqm_code);
if (m_pIter != g_map_relation.end())
{
for (int c = 0; c < (int)g_map_relation.count((char*)s_eqm_code); c++, m_pIter++)
{
if (0 != stringncasecmp(
(const char*)site_id,
(const char*)((m_pIter->second).site_id),
strlen((const char*)(m_pIter->second).site_id))) continue;
(m_pIter->second).bClose = state;
}
}
mutex_unlock(g_map_relation_mutex);
return true;
}
// 获取GIS的开关状态
unsigned char getGisOpenCloseState(unsigned char *site_id, unsigned char *s_eqm_code)
{
unsigned char isClose = 1;
map<string, ST_DEV_RELATION>::iterator m_pIter;
mutex_lock(g_map_relation_mutex);
m_pIter = g_map_relation.find((char*)s_eqm_code);
if (m_pIter != g_map_relation.end())
{
for (int c = 0; c < (int)g_map_relation.count((char*)s_eqm_code); c++, m_pIter++)
{
if (0 != stringncasecmp(
(const char*)site_id,
(const

@ -0,0 +1,904 @@
/****************************************************************************
** File name : HTOpencvImg.cpp
** Description : define Opencv function
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTOpencvImg.h"
static const char *_FILE_ = "HTOpencvImg.cpp";
static FILE *fpIni = NULL; // opencv config file handle.
static map<string, ST_OPENCV_CONF> g_conf_img;
/*************************************************************************
Function iniGetString
Rectives a character string from the specified section in the
specified inifile
Param In :
pszSection : address of section
pszEntry : address of entry
uiBufLen : size of destination buffer
pszFileName: address of inifile name
Param Out :
pszRetBuf : destination buffer
Return Code :
0 : success
<0 : failed
*************************************************************************/
static int iGetString(const char *pszSection, const char *pszEntry, char *pszRetBuf, unsigned int uiBufLen)
{
//FILE *fpIni;
char szBuf[DEF_BUFFER_1K + 1], *psz1, *psz2, *psz;
int iSectFlag, iLen;
if (fpIni == NULL) {
if ((fpIni = fopen(HT_CONFIG_FILE, "r")) == NULL)
return (-1);
}
fseek(fpIni, 0, SEEK_SET);
/*** check section ***/
iSectFlag = 0;
while (!feof(fpIni)) {
if (fgets(szBuf, DEF_BUFFER_1K, fpIni) == NULL) break;
psz = szBuf;
while (*psz != '[' && *psz != '#' && *psz != '\0') psz++;
if (*psz != '[') continue;
psz++;
while (*psz == ' ' || *psz == '\t') psz++;
psz1 = psz;
while (*psz != ']' && *psz != '\0') psz++;
if (*psz == '\0') continue;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--;
*psz = '\0';
if (!strcmp(psz1, pszSection)) {
iSectFlag = 1;
break;
}
}/*** while ***/
if (!iSectFlag) {
//fclose(fpIni);
return (-1);
}
/*** check entry ***/
while (!feof(fpIni)) {
if (fgets(szBuf, DEF_BUFFER_1K, fpIni) == NULL) break;
psz = szBuf;
while (*psz == ' ' || *psz == '\t') psz++;
if (*psz == '#' || *psz == '\0') continue;
if (*psz == '[') break;
psz1 = psz;
while (*psz != '=' && *psz != '\0') psz++;
if (*psz == '\0') continue;
psz2 = psz + 1;
if (psz1 == psz) continue;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t') psz--;
*psz = '\0';
#ifdef _WIN32
if (strcmp(psz1, pszEntry)) continue;
#else
if (strcasecmp(psz1, pszEntry)) continue;
#endif
//fclose(fpIni);
psz = psz2;
while (*psz == ' ' || *psz == '\t') psz++;
psz2 = psz;
while (*psz != '#' && *psz != '\0' && !(*psz == '/' && (*(psz + 1) == '*' || *(psz + 1) == '/'))) psz++;
while (*(psz - 1) == ' ' || *(psz - 1) == '\t' || *(psz - 1) == 0x0a || *(psz - 1) == 0x0d)
{
*(psz - 1) = '\0';
psz--;
}
//*psz= '\0';
iLen = strlen(psz2);
if (psz2[iLen - 1] == 0x0a || psz2[iLen - 1] == 0x0d) psz2[iLen - 1] = 0x00;
if (iLen == 0) return (-1);
if (iLen > (int)uiBufLen) iLen = uiBufLen;
memcpy(pszRetBuf, psz2, iLen);
*(pszRetBuf + iLen) = '\0';
return (0);
}
//fclose(fpIni);
return (-1);
}
// 加载图片配置文件数据
bool iGetOpencvConf()
{
int iRet = -1, icount = 0, img_size = 0;
char szTmp[512], szSection[128], szSite_id[DEF_EQM_CODE_SIZE] = { 0 };
string strKey;
// 打开配置文件,准备加载配置参数
if (fpIni == NULL) {
if ((fpIni = fopen(HT_CONFIMG_FILE, "r")) == NULL) {
vPrtLogMsg(LOG_ERROR, errno, "open config file: %s failed.", HT_CONFIMG_FILE);
return NULL;
}
}
// 获取站点ID
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("SITE_CODE", "site_id", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get site_id parameter failed");
fclose(fpIni);
return false;
}
strcpy((char*)szSite_id, szTmp);
// 获取站点ID
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("COMMON_CONF", "img_file_min_size", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get img_file_min_size parameter failed");
fclose(fpIni);
return false;
}
img_size = atoi(szTmp);
// 获取配置项的个数
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString("CAMERA_COUNT", "CameraCount", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get CameraCount parameter failed");
fclose(fpIni);
return false;
}
icount = atoi(szTmp);
vPrtLogMsg(LOG_DEBUG, 0, "get opencv config count: %d", icount);
for (int i = 0; i < icount; i++)
{
ST_OPENCV_CONF stConf;
memset(&stConf, 0x00, sizeof(ST_OPENCV_CONF));
strcpy((char*)stConf.site_id, szSite_id); // 站点id
stConf.img_min_size = img_size;
snprintf(szSection, sizeof(szSection),"CAMERA_%03d", i + 1);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "eqm_type", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: eqm_type parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.eqm_type[0] = (szTmp[0] & 0xff);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "eqm_code", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: eqm_code parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.eqm_code, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "system_code", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: system_code parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.sys_code, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "table_type", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: table_type parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.table_type, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "name", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: name parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.name, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "sersorid", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: sersorid parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.sersorid, szTmp);
strKey = szTmp;
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "base_angle", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: base_angle parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.base_angle = (unsigned int)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "meter_type", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: meter_type parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.meter_type = (unsigned char)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "meter_units", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: meter_units parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.meter_units = (unsigned char)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "direct_Clockwise", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: direct_Clockwise parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.direct_Clockwise = (unsigned char)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "init_value", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: init_value parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.dInitVal = (double)atof(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "max_pointer_len", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: max_pointer_len parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.max_pointer_len = (unsigned int)atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "img_path", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: img_path parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.img_path, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "img_bak", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: img_bak parameter failed", szSection);
fclose(fpIni);
return false;
}
strcpy((char*)stConf.img_bak, szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "is_replace", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get is_replace parameter failed");
return false;
}
if (stringcasecmp(szTmp, "true") == 0)
stConf.is_replace = true; // 替换原文件
else stConf.is_replace = false;
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "s_height", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: s_height parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.s_height = atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "e_height", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: e_height parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.e_height = atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "s_width", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: s_width parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.s_width = atoi(szTmp);
memset(szTmp, 0x00, sizeof(szTmp));
if ((iRet = iGetString(szSection, "e_width", szTmp, sizeof(szTmp))) < 0) {
vPrtLogMsg(LOG_ERROR, iRet, "get %s: e_width parameter failed", szSection);
fclose(fpIni);
return false;
}
stConf.e_width = atoi(szTmp);
stConf.seqno = i + 1;
g_conf_img.insert(map<string, struct _CONF_IMG>::value_type(strKey, stConf));
}
fclose(fpIni);
return true;
}
// 从文件名截取sersorid
static bool bGetSersorIDOfFilename(char *filename, char *sersorid, char *pExt)
{
char *p = NULL, *s = NULL, *t = NULL;
// 文件名格式sersorID_time.jpg 或 ../img/sersorid_time.jpg
if (filename && strlen(filename) >= 17) {
p = filename + strlen((const char*)filename);
while (*p != '\\' && *p != '/' && p != filename) {
if (*p == '.') t = p + 1; // 扩展名位置
if (*p == '_') s = p; // 分隔符_位置
p--;
}
if (t) {
strcpy(pExt, t);
pExt[strlen(pExt)] = 0x00;
}
if (s) {
memcpy(sersorid, p + 1, s - p - 1);
sersorid[s - p - 1] = 0x00;
}
return true;
}
return false;
}
// 移动文件到指定目录(备份文件)
bool bBakFilename(char *filename, char *pBakPath)
{
char *p = NULL, *s = NULL, *t = NULL;
char szCmd[1024] = { 0 };
// 文件名格式sersorID_time.jpg 或 ../img/sersorid_time.jpg
if (filename && pBakPath)
{
if (iDirOrFileExist(pBakPath))
iBuildDirent(pBakPath);
#ifdef _WIN32
snprintf(szCmd, sizeof(szCmd), "move %s %s", filename, pBakPath);
#else
snprintf(szCmd, sizeof(szCmd),"mv %s %s", filename, pBakPath);
#endif
system(szCmd);
return true;
}
return false;
}
// 显示图片
void showImg(const char *title, Mat &img)
{
#ifdef _IM_SHOW
imshow(title, img);
waitKey(0);
#endif
}
int dcmp(double x)
{
if (fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
//向量点积
double Dot(Point A, Point B)
{
return A.x*B.x + A.y*B.y;
}
//向量模长
double Length(Point A)
{
return sqrt(Dot(A, A));
}
//向量叉积
double Cross(Point A, Point B)
{
return A.x*B.y - A.y*B.x;
}
//点到线段的距离
double DistancetoSegment(Point P, Point A, Point B)
{
if (A == B)return Length(P - A);
Point v1 = B - A, v2 = P - A, v3 = P - B;
if (dcmp(Dot(v1, v2))<0) return Length(v2);
else if (dcmp(Dot(v1, v3))>0) return Length(v3);
else return (fabs(Cross(v1, v2)) / Length(v1));
}
/* 获取指定目录下的*.xxx文件
pPath : path, eg: /usr/local/img/*.jpg
: "D:\\Photo and Video\\destop1\\*.jpg";
*/
int iGetImgFileList(const char *pPath, std::vector<cv::String> & image_files)
{
cv::String pattern_jpg = (char*)pPath;
//std::vector<cv::String> image_files;
try{
cv::glob(pattern_jpg, image_files);
if (image_files.size() == 0) {
//std::cout << "No image files[jpg]" << std::endl;
return 0;
}
return (int)image_files.size();
}
catch (cv::Exception &e)
{
printf("Get ImgFile List exception,msg:%s\n", e.err.c_str());
}
return 0;
}
//下面是以海康威视的某款网络摄像头为例,使用 OpenCV 的 VideoCapture 类来显示实时视频
// rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream
// 1) username 用户名,常用 admin
// 2) password 密码,常用 12345
// 3) ip 摄像头IP如 192.0.0.64
// 4) port 端口号,默认为 554
// 5) codec 视频编码模式,有 h264、MPEG - 4、mpeg4 等
// 6) channel 通道号起始为1例如通道1则为 ch1
// 7) subtype 码流类型,主码流为 main辅码流为 sub
int showRtspVideoStream(const char* rtsp_url)
{
// "rtsp://admin:a1234567@192.168.5.186:554/MPEG-4/ch1/main/av_stream";
String rtsp_addr = rtsp_url;
VideoCapture cap(rtsp_addr);
if (!cap.isOpened()) return -1;
// cap.open(rtsp_addr);
Mat frame;
for (;;) {
cap >> frame;
if (frame.empty()) break;
imshow("Video Stream", frame);
if (waitKey(10) == 'q') break;
}
cap.release(); // 关闭视频流。
return 0;
}
// 播放视频流
int showRtspVideoStreams(const char *rtsp_url)
{
//打开视频文件其实就是建立一个VideoCapture结构
VideoCapture capture(rtsp_url);
//检测是否正常打开:成功打开时isOpened返回ture
if (!capture.isOpened()) {
cout << "fail to open!" << endl;
return 0;
}
//获取整个帧数
long totalFrameNumber = (long)capture.get(CV_CAP_PROP_FRAME_COUNT);
cout << "整个视频共" << totalFrameNumber << "" << endl;
//设置开始帧()
long frameToStart = 300;
//capture.set( CV_CAP_PROP_POS_FRAMES, frameToStart);
cout << "从第" << frameToStart << "帧开始读" << endl;
//设置结束帧
int frameToStop = 400;
if (frameToStop < frameToStart)
{
cout << "结束帧小于开始帧,程序错误,即将退出!" << endl;
return -1;
}
else
{
cout << "结束帧为:第" << frameToStop << "" << endl;
}
//获取帧率
double rate = capture.get(CV_CAP_PROP_FPS);
cout << "帧率为:" << rate << endl;
//定义一个用来控制读取视频循环结束的变量
bool stop = false;
//承载每一帧的图像
Mat frame;
//显示每一帧的窗口
namedWindow("Extracted frame");
//两帧间的间隔时间:
int delay = 1000 / (int)rate;
//利用while循环读取帧
//currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
long currentFrame = frameToStart;
//滤波器的核
int kernel_size = 3;
Mat kernel = Mat::ones(kernel_size, kernel_size, CV_32F) / (float)(kernel_size*kernel_size);
while (!stop)
{
//读取下一帧
if (!capture.read(frame))
{
cout << "读取视频失败" << endl;
return -1;
}
//这里加滤波程序
imshow("Extracted frame", frame);
//filter2D(frame, frame, -1, kernel);
//imshow("after filter", frame);
//cout << "正在读取第" << currentFrame << "帧" << endl;
//waitKey(int delay=0)当delay ≤ 0时会永远等待当delay>0时会等待delay毫秒
//当时间结束前没有按键按下时,返回值为-1否则返回按键
int c = waitKey(delay);
//按下ESC或者到达指定的结束帧后退出读取视频
if ((char)c == 27 /*|| currentFrame > frameToStop*/)
{
stop = true;
}
//按下按键后会停留在当前帧,等待下一次按键
if (c >= 0)
{
waitKey(0);
}
currentFrame++;
}
//关闭视频文件
capture.release();
return 0;
}
// 截取图片指定区域并保存
// isReplace = true: 覆盖原文件,不保留原文件,文件名不变
// = false: 保留原文件,并将截图文件命名为 xxx_cut.xxx
int vCutImageSave(ST_OPENCV_CONF *stConf, char* path_filename)
{
char szDest[MAX_PATH] = { 0 }, ext[8] = { 0 };
int shigh, ehigh, swidth, ewidth;
Mat image;
try{
image = imread(path_filename);
}
catch (cv::Exception &e)
{
printf("imread exception,msg:%s\n", e.err.c_str());
return RET_FAIL;
}
int w = image.cols; // 列数
int h = image.rows; // 行数
vPrtLogMsg(LOG_DEBUG, RET_OK, "file:%s, source high=%d width=%d", path_filename, h, w);
shigh = stConf->s_height;
ehigh = stConf->e_height;
swidth = stConf->s_width;
ewidth = stConf->e_width;
if (shigh > h) shigh = 10; // 起始高度>总高度时,起始高度=10
if (ehigh > h) ehigh = h; // 结束高度>总高度时,结束高度=h
if (swidth > w) swidth = 10; // 结束宽度>总宽度时,起始宽度=10
if (ewidth > w) ewidth = w; // 结束宽度>总宽度时,结束宽度=w
//showImg("SRC:", image);
// 0列-h-y 27列-w-x
// 0行 +-------------------------+
// 1行 | |
// 2行 | |
// 3行 | |
// 4行 | |
// 5行 +-------------------------+ 5行,27列
//
// Range(起始行,结束行), Range(起始列,结束列),
Mat image_roi(image, Range(shigh, ehigh), Range(swidth, ewidth));
if (image_roi.empty()) {
vPrtLogMsg(LOG_WARNG, RET_FAIL, "cut picture:%s to high=(%d,%d) width=(%d,%d) failed.", path_filename, shigh, ehigh, swidth, ewidth);
return RET_FAIL;
}
showImg("CUT PIC:", image_roi);
if (!stConf->is_replace)
{
bGetSersorIDOfFilename(path_filename, szDest, ext);
// 保留原文件,并重命名
snprintf(szDest, sizeof(szDest), "%s", path_filename);
memset(szDest + strlen(szDest) - strlen(ext) - 1, 0x00, sizeof(szDest)-strlen(szDest) + 1);
strcat(szDest, "_cut");
snprintf(szDest + strlen(szDest), sizeof(szDest), ".%s", ext);
imwrite(szDest, image_roi);
strcpy(path_filename, szDest); // 返回新文件名
}
else imwrite(path_filename, image_roi); // 不保留原文件,覆盖原文件
return RET_OK;
}
// 查表获取指针读数
static double dGetReadValueOf3ex5050(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 30;
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
while (g_YB_3EX5050[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_3EX5050[i].du) return g_YB_3EX5050[i].val;
if (tmp_du == g_YB_3EX5050[i + 1].du) return g_YB_3EX5050[i + 1].val;
if (fabs(tmp_du - g_YB_3EX5050[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_3EX5050[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return 0.0f; // 没找到
if (g_YB_3EX5050[min_id + 1].val > 0.0)
val_inter = fabs(g_YB_3EX5050[min_id + 1].val - g_YB_3EX5050[min_id].val) / 10;
else
val_inter = fabs(g_YB_3EX5050[min_id].val - g_YB_3EX5050[min_id - 1].val) / 10;
if (min_du > 10.0)
return g_YB_3EX5050[min_id].val + (val_inter * min_du);
return fabs(g_YB_3EX5050[min_id].val - (val_inter * min_du));
}
// 查表获取指针读数
static double dGetReadValueOfJSY10(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 30;
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
while (g_YB_JSY10[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_JSY10[i].du) return g_YB_JSY10[i].val;
if (tmp_du == g_YB_JSY10[i + 1].du) return g_YB_JSY10[i + 1].val;
if (fabs(tmp_du - g_YB_JSY10[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_JSY10[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return 0.0f; // 没找到
if (g_YB_JSY10[min_id + 1].val > 0.0)
val_inter = fabs(g_YB_JSY10[min_id + 1].val - g_YB_JSY10[min_id].val) / 10;
else
val_inter = fabs(g_YB_JSY10[min_id].val - g_YB_JSY10[min_id - 1].val) / 10;
return g_YB_JSY10[min_id].val;// +val_inter;
}
// 查表获取油表指针读数
double dGetReadValueOfOCR17NI12MO2_16(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 3.3f; // ((360-90)/10)/2=13.5单个区域差13.5°
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
while (g_YB_OCR17NI12MO2_16[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_OCR17NI12MO2_16[i].du) return g_YB_OCR17NI12MO2_16[i].val;
if (tmp_du == g_YB_OCR17NI12MO2_16[i + 1].du) return g_YB_OCR17NI12MO2_16[i + 1].val;
if (fabs(tmp_du - g_YB_OCR17NI12MO2_16[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_OCR17NI12MO2_16[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return -1.0f; // 没找到
//printf("Base = %.2f°-%.2f -- input:%.2f\n", g_YB_YZFTH[min_id].du, g_YB_YZFTH[min_id].val, tmp_du);
if (tmp_du > g_YB_OCR17NI12MO2_16[min_id].du) { // 当前度大于最近的度时
val_inter = g_YB_OCR17NI12MO2_16[min_id].val + 0.02; // (min_du * 0.02 / 10); // 可能会出现负数
//printf("(%.3f-%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
else {
val_inter = g_YB_OCR17NI12MO2_16[min_id].val + (min_du * 0.02 / 10);
//printf("(%.3f+%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
return val_inter;
}
// 查表获取油表指针读数
double dGetReadValueOfOCR17NI12MO2_25(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 3.3f; // ((360-90)/10)/2=13.5单个区域差13.5°
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
while (g_YB_OCR17NI12MO2_25[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_OCR17NI12MO2_25[i].du) return g_YB_OCR17NI12MO2_25[i].val;
if (tmp_du == g_YB_OCR17NI12MO2_25[i + 1].du) return g_YB_OCR17NI12MO2_25[i + 1].val;
if (fabs(tmp_du - g_YB_OCR17NI12MO2_25[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_OCR17NI12MO2_25[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return -1.0f; // 没找到
//printf("Base = %.2f°-%.2f -- input:%.2f\n", g_YB_YZFTH[min_id].du, g_YB_YZFTH[min_id].val, tmp_du);
if (tmp_du > g_YB_OCR17NI12MO2_25[min_id].du) { // 当前度大于最近的度时
val_inter = g_YB_OCR17NI12MO2_25[min_id].val + (min_du * 0.05 / 10); // 可能会出现负数
//printf("(%.3f-%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
else {
val_inter = g_YB_OCR17NI12MO2_25[min_id].val + (min_du * 0.05 / 10);
//printf("(%.3f+%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
return val_inter;
}
// 100摄氏度的油温表读数
double dReadPointValue_Wss411_100(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 3.4f; // ((360-90)/10)/2=13.5单个区域差13.5°
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
// if (tmp_du < 45) return 10.0f;
// if (tmp_du > 315) return 0.0f; // 无效范围内的角度值,默认给最大读数.系统提示告警
if (tmp_du == 0) tmp_du = 180.0f;
while (g_YB_WSS100[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_WSS100[i].du) return g_YB_WSS100[i].val;
if (tmp_du == g_YB_WSS100[i + 1].du) return g_YB_WSS100[i + 1].val;
if (fabs(tmp_du - g_YB_WSS100[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_WSS100[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return -1.0f; // 没找到
//printf("Base = %.2f°-%.2f -- input:%.2f\n", g_YB_YZFTH[min_id].du, g_YB_YZFTH[min_id].val, tmp_du);
if (tmp_du > g_YB_WSS100[min_id].du) { // 当前度大于最近的度时
val_inter = g_YB_WSS100[min_id].val - (min_du * 2 / 10); // 可能会出现负数
}
else {
val_inter = g_YB_WSS100[min_id].val + (min_du * 2 / 10);
}
return val_inter;
}
// 150摄氏度的油温表读数
double dGetReadValueOf_WSS150(double du, double base, int linelen)
{
int i = 0, min_id = -1;
double tmp_du = du, min_du = 3.4f; // ((360-90)/10)/2=13.5单个区域差13.5°
double val_inter = 0;
if (du > base) {
tmp_du = ((int)(du * 100) % (int)(base * 100)) / 100;// +(du / base);
}
// if (tmp_du < 45) return 10.0f;
// if (tmp_du > 315) return 0.0f; // 无效范围内的角度值,默认给最大读数.系统提示告警
while (g_YB_WSS150[i].du > 0)
{
// 找du数差值最小的也就是最接近的记录。
if (tmp_du == g_YB_WSS150[i].du) return g_YB_WSS150[i].val;
if (tmp_du == g_YB_WSS150[i + 1].du) return g_YB_WSS150[i + 1].val;
if (fabs(tmp_du - g_YB_WSS150[i].du) < min_du) {
min_du = fabs(tmp_du - g_YB_WSS150[i].du);
min_id = i;
}
i++;
}
if (min_id < 0) return -1.0f; // 没找到
//printf("Base = %.2f°-%.2f -- input:%.2f\n", g_YB_YZFTH[min_id].du, g_YB_YZFTH[min_id].val, tmp_du);
if (tmp_du > g_YB_WSS150[min_id].du) { // 当前度大于最近的度时
val_inter = g_YB_WSS150[min_id].val - (min_du * 3 / 10); // 可能会出现负数
//printf("(%.3f-%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
else {
//val_inter = g_YB_WSS150[min_id].val + (min_du * 3 / 10);
val_inter = g_YB_WSS150[min_id].val + min_du ;
//printf("(%.3f+%.3f) min_du=%.3f\n", g_YB_YZFTH[min_id].val, (min_du * 0.1 / 10), min_du);
}
return val_inter;
}
//double gtest(double du, double base, int linelen)
//{
// return dGetReadValueOfYZFTH( du, base, linelen);
//}
// 遍历所有像素点1
void colorReduce(cv::Mat &inputImage, int div)
{
// 参数准备
// outputImage = inputImage.clone();
int rowNumber = inputImage.rows;
int colNumber = inputImage.cols*inputImage.channels();
if (inputImage.isContinuous()) { // 判断数据在内存是否连续存储的。
colNumber = colNumber * rowNumber;
rowNumber = 1;
}
for (int i = 0; i < rowNumber; i++)
{
// 获取第i行的首地址
uchar* data = inputImage.ptr<uchar>(i);
for (int j = 0; j < colNumber; j++) // 列循环
{
// 开始处理每一个像素值每一个像素值都减去div
data[j] = data[j] - div;
}
}
}
// using .ptr and * ++ and bitwise (continuous+channels)
void colorReduce7(cv::Mat &image, int div = 64) {
int nr = image.rows; // number of rows
int nc = image.cols; // number of columns
if (image.isContinuous()) {
// then no padded pixels
nc = nc*nr;
nr = 1; // it is now a 1D array
}
int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));
// mask used to round the pixel value
uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
for (int j = 0; j < nr; j++) {
uchar* data = image.ptr<uchar>(j);
for (int i = 0; i < nc; i++) {
if (image.channels() == 1)
*data++ = *data & mask + div / 2;
else if (image.channels() == 3) {
*data++ = *data & mask + div / 2;
*data++ = *data & mask + div / 2;
*data++ = *data & mask + div / 2;
}
} // end of row
}
}
void colorReduce(cv::Mat & inputImage)
{
// 参数准备
int a, b, c;
int rowNumber = inputImage.rows;
int colNumber = inputImage.cols*inputImage.channels();
if (inputImage.isContinuous()) { // 判断数据在内存是否连续存储的。
colNumber = colNumber * rowNumber;
rowNumber = 1;
}
for (int i = 0; i < rowNumber; i++) {
for (int j = 0; j < colNumber; j++)
{
a = inputImage.at<Vec3b>(i, j)[0];
b = inputImage.at<Vec3b>(i, j)[1];
c = inputImage.at<Vec3b>(i, j)[2];
if (a > 180) inputImage.at<Vec3b>(i, j)[0] = 0;
if (b < 50) inputImage.at<Vec3b>(i, j)[1] = 255;
if (c *data++ = *data & mask + div / 2;
else if (image.channels() == 3) {
*data++ = *data & mask + div / 2;
*data++ = *data & mask + div / 2;
*data++ = *data & mask + div / 2;
}
} // end of row
}
}
void colorReduce(cv::Mat & inputImage)
{
// 鍙傛暟鍑嗗
int a, b, c;
int rowNumber = inputImage.rows;
int colNumber = inputImage.cols*inputImage.channels();
if (inputImage.isContinuous()) { // 鍒ゆ柇鏁版嵁鍦ㄥ唴瀛樻槸鍚﹁繛缁瓨鍌ㄧ殑銆

File diff suppressed because it is too large Load Diff

@ -0,0 +1,449 @@
/******************************************************************************
** Filename : HTService.cpp
** Description: main file
** Create Date: 2018-09-08
** Auth By : Liuyx
** Update Date: 2018-09-08
** Copyrigth By: xi'an huatek, Inc Co., Ltd
******************************************************************************/
#include "HTGlobal.h"
static const char *_FILE_ = "HTService.cpp" ;
CDBMySQL* CDBMySQL::p_dbHandle = NULL;
static char is_down = 0 ;
// 终止所有业务工作线程
static void cancel_thread_work(void)
{
#ifndef _WIN32
int i = 0 ;
if(thread_handle_client) {
pthread_cancel(thread_handle_client);
pthread_join(thread_handle_client, NULL);
pthread_kill(thread_handle_client, SIGURG);
}
vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_client shutdown.") ;
if(thread_handle_linkmgr) {
pthread_cancel(thread_handle_linkmgr);
pthread_join(thread_handle_linkmgr, NULL);
pthread_kill(thread_handle_linkmgr, SIGURG);
}
vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_linkmgr shutdown.") ;
if(thread_handle_active) {
pthread_cancel(thread_handle_active);
pthread_join(thread_handle_active, NULL);
pthread_kill(thread_handle_active, SIGURG);
}
vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_active shutdown.") ;
//for(i=0; i < (int)g_TConfig.getParseThreadNumber(); i++) {
if(thread_handle_parse) {
pthread_cancel(thread_handle_parse);
pthread_join(thread_handle_parse, NULL);
pthread_kill(thread_handle_parse, SIGURG);
}
//}
vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_parse group shutdown.") ;
//
//for(i=0; i < (int)g_TConfig.getOprationThreadNumber(); i++) {
// if(thread_handle_opration[i]) {
// pthread_cancel(thread_handle_opration[i]);
// pthread_join(thread_handle_opration[i], NULL);
// pthread_kill(thread_handle_opration[i], SIGURG);
// }
//}
//vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_opration group shutdown.") ;
//for(i=0; i < (int)g_TConfig.getResponeThreadNumber(); i++) {
if(thread_handle_active) {
pthread_cancel(thread_handle_active);
pthread_join(thread_handle_active, NULL);
pthread_kill(thread_handle_active, SIGURG);
}
//}
vPrtLogMsg(LOG_DEBUG, RET_OK,"thread_handle_respone group shutdown.") ;
#endif
}
static void sig_exit(int signo)
{
vPrtLogMsg(LOG_DEBUG, errno,"recv signal, service shutdown.sig:%d", signo ) ;
cancel_thread_work();
vPrtLogMsg(LOG_DEBUG, errno,"unloading service is done...1");
g_Running = 0 ; // 先停止所有的业务线程
_SLEEP(1000*2);
vPrtLogMsg(LOG_DEBUG, errno,"unloading service is done...2");
unLoadServiceEvent();// 卸载运行配置
is_down = 0 ;
vPrtLogMsg(LOG_DEBUG, errno,"unloading service is done.");
}
void sig_chld(int signo)
{
#ifndef _WIN32
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
vPrtLogMsg(LOG_DEBUG, RET_OK, "child %d terminated\n", pid);
#endif
return;
}
// 创建守护进程环境
static int HTStartBackgroundProcess()
{
#ifndef _WIN32
pid_t pid;
// 1.转变为后台进程
if ((pid = fork() ) != 0 )
exit( 0);
// 2.离开原先的进程组
setsid();
// 3.禁止再次打开控制终端
if ((pid = fork() ) != 0 )
exit( 0);
// 4.关闭打开的文件描述符,避免浪费系统资源
/*
rlimit rlim;
if(getrlimit(RLIMIT_NOFILE,&rlim) == 0)
{
for(int fd=3; fd<=(int)rlim.rlim_cur; fd++)
{
close(fd);
}
}
*/
// 5.改变当前的工作目录,避免卸载不了文件系统
//if (chdir("/") == -1) exit(1);
// 6.重设文件掩码,防止某些属性被父进程屏蔽
umask(0);
setpgrp();
// 7.重定向标准输入,输出,错误流,因为守护进程没有控制终端
/*
if ((fd = open("/dev/null", O_RDWR)) == -1)
exit(1);
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
*/
signal(SIGINT, sig_exit); // Program terminated with signal 11, Segmentation fault.
signal(SIGTERM, sig_exit);
// 8.屏蔽信号
signal( SIGHUP, SIG_IGN);
signal( SIGQUIT, SIG_IGN);
signal( SIGPIPE, SIG_IGN);
signal( SIGTTOU, SIG_IGN);
signal( SIGTTIN, SIG_IGN);
signal( SIGCHLD, SIG_IGN);
struct sigaction sig;
sig.sa_handler = SIG_IGN;
sig.sa_flags = 0;
sigemptyset( &sig.sa_mask);
sigaction( SIGHUP,&sig,NULL);
#endif
return 0;
}
void getcptime(unsigned char *data, int len)
{
SYSTEMTIME st ;
st.wMilliseconds = (data[0]+ 256 * data[1])%1000;
st.wSecond = (data[0] + 256 * data[1])/1000;
st.wMinute = data[2] & 0x3f;
st.wHour = data[3]&0x1f;
st.wDay = data[4]&0x1f;
st.wMonth = data[5]&0x0f;
st.wYear = data[6] & 0x7f;
}
static void Usage(char *prgname)
{
printf("==>> Usage: \n");
printf(" %s [start | stop | version] [img_file shigh ehigh swidth ewidth[tabtype 180 | 360]]\n", prgname);
printf("Parameters:\n");
printf(" --> img_file ... Pictures file path and name\n");
printf(" --> shigh ... Pictures's start high pointer\n");
printf(" --> ehigh ... Pictures's end high pointer\n");
printf(" --> swidth ... Pictures's start width pointer\n");
printf(" --> ewidth ... Pictures's end width pointer\n");
// add by ramon 2019-06-27, add TYPE=xxxx
printf(" --> tabtype:[TYPE] ... Pictures's end width pointer,TYPE=3EX5050 | JSY-10 | YZF250TH\n");
printf("Examples:\n");
printf(" --> %s start ... Startup Service\n", prgname);
printf(" --> %s stop ... Shutdown Service\n", prgname);
printf(" --> %s ./img.jpg 10 200 50 210 ... Clipping pictures to high(10,200) width(50,210)\n", prgname);
// add by ramon 2019-06-27, add TYPE=xxxx
printf(" --> %s ./img.jpg TYPE 180|360 ... Get pictuer point value, TYPE=3EX5050|JSY-10|YZF250TH\n", prgname);
printf(" --> %s ./img.jpg 10 200 50 210 JSY-10 360 ... Clipping pictures and get point number\n", prgname);
printf(" --> %s ./img.jpg 10 200 50 210 3EX5050 180 ... Clipping pictures and get point number\n", prgname);
printf(" --> %s ./img.jpg 10 200 50 210 YZF250TH 360 ... Clipping pictures and get point number\n", prgname); // add by ramon 2019-06-27
printf("Version:\n");
//printf(" %s version %s Copyright (c) 2020 the Huatek developers group.\n", prgname, HT_VERSION_BUILD_ID);
printf(" %s version %s Copyright (c) 2020 the Xydl developers group.\n", prgname, HT_VERSION_BUILD_ID);
}
static void task_kill()
{
char szCmd[128] = { 0 };
int pid = iGetPid();
#ifdef _WIN32
sprintf(szCmd, "taskkill /PID %d /F", pid);
#else
sprintf(szCmd, "kill -9 %d >/dev/null 2>&1", pid);
#endif
system(szCmd);
}
#if 1
int main(int argc, char* argv[])
{
//char szTime[] = "20191122140322";
//char szOut[32] = { 0 };
//double dOilTempOuter = -9999.0f, dInitValue = -9999.0f;
//vFormatTimes(szTime, szOut);
//printf("szTime=%s out=%s\n", szTime, szOut);
//for (int i = 0; i < 100; i++)
// printf("%s\n", double2str(dOilTempOuter, dInitValue, szOut));
//getchar();
if (argc != 2 && argc != 4 && argc != 6 && argc != 8) {
Usage(argv[0]);
return 0;
}
if (argc == 4) //获取图片指针读数
{
vInitLogMutex(); // 初始化log文件锁与句柄
g_TConfig.getIniConfig();
ST_OPENCV_CONF stConf;
strcpy((char*)stConf.img_path, argv[1]);
stConf.is_replace = false;
strcpy((char*)stConf.table_type, argv[2]);
stConf.base_angle = atoi(argv[3]);
stConf.dInitVal = 1;
printf("-->> Table type:[%s] Base_angle:[%d°]\n", argv[2], stConf.base_angle);
if (stringncasecmp("JSY-10", argv[2], strlen("JSY-10")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_JSY10(&stConf, argv[1]));
else if (stringncasecmp("3EX5050", argv[2], strlen("3EX5050")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_3EX5050(&stConf, argv[1]));
// add by ramon 2019-06-27
else if (stringncasecmp("YZF250TH", argv[2], strlen("YZF250TH")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_JSY10(&stConf, argv[1]));
// add by ramon 2019-06-27
else printf("ERROR-->> Unkonw table type:%s, TYPE: JSY-10|3EX5050|YZF250TH", argv[2]);
//getchar();
return 0;
}
if (argc == 6) // 截图工具方式
{
ST_OPENCV_CONF stConf;
strcpy((char*)stConf.img_path, argv[1]);
stConf.s_height = atoi(argv[2]);
stConf.e_height = atoi(argv[3]);
stConf.s_width = atoi(argv[4]);
stConf.e_width = atoi(argv[5]);
stConf.is_replace = false;
vCutImageSave(&stConf, argv[1]);
printf("-->> Clipping pictures:[%s] to :[%s] ... complete.\n", stConf.img_path, argv[1]);
return 0;
}
if (argc == 8) //获取图片指针读数
{
vInitLogMutex(); // 初始化log文件锁与句柄
g_TConfig.getIniConfig();
ST_OPENCV_CONF stConf;
strcpy((char*)stConf.img_path, argv[1]);
stConf.s_height = atoi(argv[2]);
stConf.e_height = atoi(argv[3]);
stConf.s_width = atoi(argv[4]);
stConf.e_width = atoi(argv[5]);
stConf.is_replace = false;
stConf.dInitVal = 5.8f;
strcpy((char*)stConf.table_type, argv[6]);
stConf.base_angle = atoi(argv[7]);
vCutImageSave(&stConf,argv[1]);
printf("-->> Clipping pictures:[%s] to :[%s] ... complete.\n", stConf.img_path, argv[1]);
printf("-->> Table type:[%s] Base_angle:[%d°]\n", (char*)stConf.table_type, stConf.base_angle);
if (stringncasecmp("JSY-10", argv[6], strlen("JSY-10")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_JSY10(&stConf, argv[1]));
else if (stringncasecmp("3EX5050", argv[6],strlen("3EX5050")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_3EX5050(&stConf, argv[1]));
// add by ramon 2019-06-27
else if (stringncasecmp("YZF250TH", argv[6], strlen("YZF250TH")) == 0)
printf("-->> ReadPoint: [%s] read num: %.2f\n", argv[1], dReadPointValue_JSY10(&stConf, argv[1]));
else printf("ERROR-->> Unkonw table type:%s, TYPE: JSY-10|3EX5050|YZF250TH", argv[6]);
return 0;
}
if (argc == 2) {
if (!stringcasecmp("start", argv[1])) {
int i = 0;
is_down = 1;
if (RET_OK != loadServiceEvent()) return 0; // 加载运行配置
HTStartBackgroundProcess();
HTInitThreadHandle();
vSetPid(); // 记录PID
ht_pthread_create_background(&thread_handle_cache,thread_cache_proc,NULL); // 内存数据同步线程
#ifdef _HT_IEC104_APP
ht_pthread_create_background(&thread_handle_warning, thread_warn_proc, NULL); // 告警处理线程
ht_pthread_create_background(&thread_handle_origin, thread_origin_proc, NULL); // 原始数据入库线程
ht_pthread_create_background(&thread_handle_pingce, thread_pingce_proc, NULL); // 评测数据入库线程
ht_pthread_create_background(&thread_handle_gishold, thread_gis_hold_proc, NULL); // 评测数据入库线程
ht_pthread_create_background(&thread_handle_linkmgr, thread_client_proc, NULL); // 链路管理线程
ht_pthread_create_background(&thread_handle_parse, thread_parser_proc, NULL); // 104报文解析线程
ht_pthread_create_background(&thread_handle_timer, thread_Timer_proc, NULL); // 104链路超时管理线程
ht_pthread_create_background(&thread_handle_active, thread_active_proc, NULL); // 104报文应答线程
#endif
#ifdef _HT_OPENCV_APP
ht_pthread_create_background(&thread_handle_opecvimg, thread_opencv_proc, NULL); // 图片解析线程
#endif
printf("Service start ...... OK\n");
while (1) {
if (!is_down) break;
_SLEEP(2000);
}
vPrtLogMsg(LOG_DEBUG, 0, "free manager database connection pool:%s/%s@%s successed!",
g_TConfig.getdbUserName(), g_TConfig.getdbUserPass(), g_TConfig.getdbName());
vPrtLogMsg(LOG_DEBUG, 0, "HTService shutdown completed immediately!");
vFreeLogMutex(); // 关闭log文件锁与句柄
return 0;
}
if (!stringcasecmp("stop", argv[1])) {
task_kill();
printf("Service stop ...... OK\n");
return 0;
}
if (!stringcasecmp("version", argv[1])) {
printf("--> %s version %s Copyright (c) 2020 the Xydl developers group.\n", argv[0], HT_VERSION_BUILD_ID);
return 0;
}
}
Usage(argv[0]);
return 0;
}
#else
bool bSetPointTableValue(unsigned char *v, int len, unsigned int adr, char stype)
{
unsigned char cval = 0;
float fval = 0;
switch (stype)
{
case 1: // 遥信量
if (v) cval = ((unsigned char)v[0] & 0xff);
printf("cval=%d\n", cval);
break;
case 2: // 遥测量
if (v) memcpy(&fval, &v, len);
printf("fval=%.3f\n", fval);
break;
default:
break;
}
return true;
}
//计算得到指针指向的角度 theta直接测量可以得到指针刻度起点所对应的角度 minangle
//以及终止角度maxangle以及最大刻度量 10.
//则可以得到实际的示数:
//
//value = theta - minangle) * 10 / (maxangle - minangle)
//
//利用这个公式对上图的示数进行计算,
//
//minangle = 60 maxangle = 320 最大刻度量 10theta = 220
//
//value = 220 - 60 * 10 / 320 - 60 = 6.15384615....
//
//接近真实数值,当然为了获得尽可能准确的数值,我们需要精确的 minangle maxangle 以及theta
///////////////////////////////
//指针所在的线段是我们通过霍夫检测得到的,
//所以我们可以得到线段的两个端点 a(x1, y1) b(x2, y2)
//计算线段的 tan(theta), 然后计算反三角函数得到 theta
//前面我们得到圆的一些基本参数:圆心坐标 c(x, y), 半径 r
//假设 a 是离圆心的近点b 是远点
//
//x_angle = x2 - x
//y_angle = y - y2
//
//一定要注意这里是 y - y2不是 y2 - y
//这是因为对图像所在的笛卡尔直角坐标系00点在图像的左上角
//所以越往下 y 越大。
//
//则有 tan(theta) = y_angle / x_angle theta = arctan(tan(theat))
/////////////////////////////
//1(x_angle > 0 and y_angle >0) or(x_angle > 0 and y_angle < 0)
//
// final_theta = 270 - theta
//
// 但是这包含了两种小情况,前半部分说明指针的终点在右半部分的上半部分,
// theta > 0, final_theta < 270后半部分说明指针的终点在右半部分的
// 下半部分theta < 0, final_theta > 270.
//(2) (x_angle < 0 and y_angle >0) or(x_angle < 0 and y_angle < 0)
//
// final_theta = 90 - theta
//
// 依然是两种情况,前半部分说明指针指向的是左半部分的上半部分,
// theta < 0, final_theta > 90; 后半部分说明指针指向了左半部分的
// 下半部分theta > 0, final_theta < 90
void genWainningTables()
{
}
/** @函数 main */
int main(int argc, char** argv)
{
// vInitPress_OCR17NI12MO2_16();
if (argc == 6) // 截图工具方式
{
ST_OPENCV_CONF stConf;
strcpy((char*)stConf.img_path, argv[1]);
stConf.s_height = atoi(argv[2]);
stConf.e_height = atoi(argv[3]);
stConf.s_width = atoi(argv[4]);
stConf.e_width = atoi(argv[5]);
stConf.is_replace = false;
vCutImageSave(&stConf, argv[1]);
printf("-->> Clipping pictures:[%s] to :[%s] ... complete.\n", stConf.img_path, argv[1]);
//return 0;
}
HTImgAnalys(argv[1]);
return 0;
}
#endif

@ -0,0 +1,518 @@
/****************************************************************************
** File name : FLTTcpSocket.h
** Description : define common api for tcp socket
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
// #include "StdAfx.h"
#include <errno.h>
#include "HTGlobal.h"
#include "HTTcpSocket.h"
static const char *_FILE_ ="HTTcpSocket.cpp" ;
TTcpSocket::TTcpSocket()
{
m_tcpPort = 0 ;
m_server_fd = -1;
m_sockid = -1;
#ifdef _WIN32
WSADATA Data ;
WSAStartup(MAKEWORD(2, 2), &Data) ;
#endif
}
TTcpSocket::~TTcpSocket()
{
#ifdef _WIN32
WSACleanup();
#endif
}
void TTcpSocket::tcpSetServerfd(int fd)
{
if (fd > 0) m_server_fd = fd;
}
void TTcpSocket::tcpSetSockID(int fd)
{
if (fd > 0) m_sockid = fd;
}
int TTcpSocket::tcpGetServerfd()
{
return m_server_fd;
}
int TTcpSocket::tcpGetSockID()
{
return m_sockid;
}
//关闭socket
int TTcpSocket::tcpCloseSocket(int sockfd)
{
if(sockfd > 0) {
#ifdef _WIN32
//if(_close(sockfd) == -1)
if(shutdown(sockfd, 2) == -1)
#else
if(close(sockfd) == -1)
#endif
// vPrtLogMsg(LOG_WARNG, RET_FAIL, "_close sockid=%d return:%d:%s",sockfd, errno, strerror(errno));
return 1;
}
return 0 ;
}
void TTcpSocket::SetSocketMode(int sockid, int iMode)
{
//将SOCKET置为非阻塞的I/O
#ifndef _WIN32
if (fcntl(sockid, F_SETFL, (fcntl(sockid, F_GETFL) | O_NONBLOCK)) == -1) {
vPrtLogMsg(LOG_WARNG, errno,"error occured when fcntl,sockid:%d msg:%s.",sockid, strerror(errno));
return ;
}
#else
unsigned long flag = iMode ; //0:阻塞模式 1:非阻塞方式
if((ioctlsocket(sockid, FIONBIO, &flag)) < 0) {
vPrtLogMsg(LOG_WARNG, errno,"error occured when ioctlsocket,sockid:%d msg:%s.",sockid, strerror(errno));
return ;
}
#endif
}
// 根据sockid获取源地址和源端口
int TTcpSocket::getPeerInfo(int sockid, unsigned char *sip, unsigned short *sport)
{
if(sockid < 0) return -1;
struct sockaddr_in clientaddr;
#ifndef _WIN32
socklen_t clilen =sizeof(struct sockaddr_in); ;
#else
int clilen = sizeof(struct sockaddr_in) ;
#endif
if(getpeername(sockid, (struct sockaddr *)&clientaddr, &clilen) < 0) {
vPrtLogMsg(LOG_ERROR, errno, "getpeername failed, sockid=%d", sockid);
return -1;
}
strcpy((char*)sip, inet_ntoa(clientaddr.sin_addr));
*sport = ntohs(clientaddr.sin_port);
return 0;
}
// 根据sockid获取目标地址和目标端口
int TTcpSocket::getLocalSocketInfo(int sockid, unsigned char *sip, unsigned short *sport)
{
if(sockid < 0) return -1;
struct sockaddr_in clientaddr;
#ifndef _WIN32
socklen_t clilen =sizeof(struct sockaddr_in); ;
#else
int clilen = sizeof(struct sockaddr_in) ;
#endif
if(getsockname(sockid, (struct sockaddr *)&clientaddr, &clilen) < 0) {
vPrtLogMsg(LOG_ERROR, errno, "getpeername failed, sockid=%d", sockid);
return -1;
}
strcpy((char*)sip, inet_ntoa(clientaddr.sin_addr));
*sport = ntohs(clientaddr.sin_port);
return 0;
}
//创建socket TCP服务。
// return val : 0 -- successed
// : <0 -- failed
int TTcpSocket::tcpOpenServer(const char *ip,unsigned short port)
{
int m_sockfd = -1;
if(!(port > 1024 && port < 65535) )
{
vPrtLogMsg(LOG_ERROR, ErrSockParam, "server port:%d is invalid(1024-65535)", port);
return ErrSockParam;
}
m_tcpPort = port;
setvbuf(stdin,NULL,_IONBF,MAX_SBUFF_TCP);
setvbuf(stdout, NULL, _IONBF, MAX_SBUFF_TCP);
//创建SOCKET对象
m_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(m_sockfd == -1)
{
vPrtLogMsg(LOG_ERROR, ErrOpenServer, "create socket error,msg:%s.",strerror(errno));
return ErrOpenServer;
}
//将SOCKET置为非阻塞的I/O
// SetSocketMode(m_sockfd) ;
struct sockaddr_in fsock;
int iRet = -1;
#ifndef _WIN32
bzero((char *)&fsock, sizeof(struct sockaddr_in)) ;
#else
memset(&fsock, 0x00, sizeof(struct sockaddr_in)) ;
#endif
fsock.sin_family=AF_INET;
fsock.sin_port=htons(m_tcpPort);
fsock.sin_addr.s_addr=htoni(INADDR_ANY);
if (ip) fsock.sin_addr.s_addr=inet_addr(ip);
int iFlag = 1;
#ifndef _WIN32
if(setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&iFlag, sizeof(iFlag)) != 0)
#else
if(setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&iFlag, sizeof(iFlag)) != 0)
#endif
{
vPrtLogMsg(LOG_ERROR, ErrSetSockOpt,"setsockopt of so_reuseaddr error."
"sockid:%d msg:%s.",m_sockfd, strerror(errno)) ;
tcpCloseSocket(m_sockfd) ;
return ErrSetSockOpt ;
}
if((iRet = bind(m_sockfd, (struct sockaddr*)&fsock, sizeof(fsock))) == -1)
{
vPrtLogMsg(LOG_ERROR, ErrBindFail, "socket bind error,sockid:%d msg:%s.",m_sockfd, strerror(errno)) ;
tcpCloseSocket(m_sockfd) ;
return ErrBindFail;
}
if((iRet = listen(m_sockfd, LISTENQ)) == -1)
{
vPrtLogMsg(LOG_ERROR, ErrListenFail,"socket listen error,sockid:%d msg:%s.",m_sockfd, strerror(errno)) ;
tcpCloseSocket(m_sockfd) ;
return ErrListenFail;
}
// m_tcpConnected = true ;
vPrtLogMsg(LOG_DEBUG, 0, "Acceptting on %s:%d, waitting request...",ip,m_tcpPort) ;
return m_sockfd ;
}
//侦听是否有连接请求
int TTcpSocket::tcpAcceptSocket(int sockid)
{
fd_set fd_Read ;
struct timeval st_TimeOut ;
int isel = 0 ;
int iClientID = -1 ;
struct sockaddr_in cliaddr;
#ifndef _WIN32
socklen_t cliAddrLen = sizeof(sockaddr_in) ;
#else
int cliAddrLen = sizeof(sockaddr_in) ;
#endif
st_TimeOut.tv_sec = 5 ;
st_TimeOut.tv_usec = 0;
FD_ZERO(&fd_Read);
FD_SET((unsigned int)sockid, &fd_Read);
isel = select(sockid + 1 , &fd_Read, NULL, NULL, &st_TimeOut);
if(isel == 0 || isel == EINTR) {
// vPrtLogMsg(LOG_DEBUG, errno, "accept...isel=%d errno=%d",isel, errno);
return -1 ;
}
else if( FD_ISSET(sockid , &fd_Read) )
{
iClientID = accept(sockid, (struct sockaddr*)&cliaddr, &cliAddrLen);
if(iClientID > 0)
{
vPrtLogMsg(LOG_DEBUG, 0,"Have once new link from %s:%d sockid:%d.",
inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port), iClientID) ;
}
else {
vPrtLogMsg(LOG_DEBUG, errno, "accept...isel=%d errno=%d",isel, errno);
return -1;
}
}
SetSocketMode(iClientID); //设置为非阻塞
int iFlag = 1;
#ifndef _WIN32
if(setsockopt(iClientID, SOL_SOCKET, SO_REUSEADDR, (const void *)&iFlag, sizeof(iFlag)) != 0)
#else
if(setsockopt(iClientID, SOL_SOCKET, SO_REUSEADDR, (const char *)&iFlag, sizeof(iFlag)) != 0)
#endif
{
vPrtLogMsg(LOG_ERROR, ErrSetSockOpt,"setsockopt of so_reuseaddr error,sockid:%d msg:%s.",iClientID, strerror(errno)) ;
tcpCloseSocket(iClientID) ;
return ErrSetSockOpt ;
}
tcpSetlinger(iClientID);
return iClientID ;
}
/************************************************************
** Description : send data for TCP/IP
** Para in : tcpID TCP/IP socket description
** *buf send data buffer
** length send data size
** Para out : None
** Return Code : >0 send data length
** <0 error
************************************************************/
int TTcpSocket::tcpSendBuffer(int sockid, const char *pBuffer, int length)
{
if ((sockid <= 0) || (pBuffer == NULL) )
return -1 ;
if(length <= 0) length = strlen(pBuffer);
int iSendLen = 0,iLen=0,i=0,iCnt=0,len=length ;
char *p = (char *)pBuffer;
fd_set fd_Write, fd_Except ;
struct timeval st_TimeOut ;
if(length > MAX_SBUFF_TCP)
iCnt = length/MAX_SBUFF_TCP ;
else
iCnt = 0 ;
for(;;)
{
FD_ZERO(&fd_Write) ;
FD_ZERO(&fd_Except) ;
FD_SET((unsigned int)sockid, &fd_Write) ;
FD_SET((unsigned int)sockid, &fd_Except) ;
iSendLen = -1 ;
st_TimeOut.tv_sec = 0 ;
st_TimeOut.tv_usec = 10 ;
iSendLen = select (sockid+1 , NULL, &fd_Write, &fd_Except, &st_TimeOut) ;
if((iSendLen == 0 && errno == EPIPE) || (iSendLen < 0)) { // EPIPE =32 Broken pipe EBADF=9 Bad file number
vPrtLogMsg(LOG_ERROR,errno, "socket execption close,sockid:%d ret:%d msg:%s", sockid, iSendLen, strerror(errno));
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrException;
}
if( FD_ISSET(sockid, &fd_Except) )
{
vPrtLogMsg(LOG_ERROR,errno, "socket execption,sockid:%d msg:%s", sockid, strerror(errno));
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrSendFail ; //socket exception
}
else if( FD_ISSET(sockid , &fd_Write) )
{
iSendLen = 0 ;
for(i=0; i< iCnt; i++)
{
iLen = send(sockid, p+(i*MAX_SBUFF_TCP), MAX_SBUFF_TCP,0);
if( iLen < 0 )
{
vPrtLogMsg(LOG_ERROR,errno, "send buffer fail,sockid:%d toplen:%ld sendlen:%d msg:%s",
sockid, len, iSendLen, strerror(errno));
if(errno == 0 && iLen == -1) {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrException;
}
if(errno == EPIPE || errno == EBADF || errno == ECONNRESET || errno == EINVAL) {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrException;
}
else {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrSendFail ; // send data fail
}
}
length -= MAX_SBUFF_TCP;
iSendLen += iLen ;
}
if(length == 0 ) {
//add_monitor_mesg(len, 0x01, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return iSendLen ;
}
if(length >0)
{
iLen = send(sockid, p+(i*MAX_SBUFF_TCP), length,0);
if(iLen < 0)
{
vPrtLogMsg(LOG_ERROR, errno, "send buffer fail! sockid:%d toplen:%ld sendlen:%d msg:%s",
sockid, len, iSendLen, strerror(errno));
if(errno == 0 && iLen == -1) {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrException;
}
if(errno == EPIPE || errno == EBADF || errno == ECONNRESET || errno == EINVAL) {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrException;
}
else {
//add_monitor_mesg(len, 0x00, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return ErrSendFail ; // send data fail
}
}
break ;
}
}
} //end for(;;)
//add_monitor_mesg(iSendLen+iLen, 0x01, (unsigned char*)pBuffer); // 添加监控消息到监控发送队列
return (iSendLen+iLen);
}
/************************************************************
** Description : recv data for TCP/IP
** Para in : tcpID TCP/IP socket description
** *buf send data buffer
** length send data size
** Para out : None
** Return Code : >0 recv data length
** <0 error
************************************************************/
int TTcpSocket::tcpRecvBuffer(int sockid, char* pBuffer,int nMaxLength, int timeout)
{
int nLength = -2;
int iTop = 0;
fd_set fd_Read,fd_Except;
struct timeval st_TimeOut;
int isel = 0;
if( sockid <= 0 || pBuffer == NULL) return -1;
while(iTop != nMaxLength)
{
st_TimeOut.tv_sec = timeout ;
st_TimeOut.tv_usec = 0;
FD_ZERO(&fd_Read);
FD_ZERO(&fd_Except) ;
FD_SET((unsigned int)sockid, &fd_Read) ;
FD_SET((unsigned int)sockid, &fd_Except) ;
isel= select (sockid + 1 , &fd_Read, NULL, &fd_Except, &st_TimeOut) ;
if(isel <= 0 || isel == EINTR)
{
// vPrtLogMsg(LOG_DEBUG,errno, "select socket timeout,isel=%d",isel);
break ;
}
else if( FD_ISSET(sockid, &fd_Except) )
{
vPrtLogMsg(LOG_ERROR,errno,"socket execption,sockid:%d errno:%d iselect:%d", sockid, errno, isel) ;
return ErrRecvFail; // recv fail
}
else if (isel > 0) //EINTR
{
if (FD_ISSET(sockid,&fd_Read)) //检测Socket读状态
{
nLength = recv(sockid, pBuffer, MAX_SBUFF_TCP, MSG_PEEK); // MSG_PEEK
if ( nLength < 0 && (errno == EPIPE || errno == EBADF || errno == ECONNRESET || errno == EINVAL))
return ErrException;
else if( isel == 1 && nLength == 0 && (errno == EPIPE || errno == EBADF || errno == ECONNRESET || errno == EINVAL)) {
vPrtLogMsg(LOG_DEBUG,errno, "select socket timeout,isel=%d nLength=%d",isel,nLength);
return ErrException; // iTop; //检查到客户端主动断开连接.
}
else if(nLength < 0 && errno == 0)
return ErrException ;
else if (nLength < 0)
return ErrRecvFail; // recv fail
else if (nLength == 0)
return ErrException;
else {
iTop += nLength;
}
}
break ;
}
}
return iTop;
}
//连接是否已经建立
bool TTcpSocket::tcpIsConnected(int sockid)
{
char msg[5] = {0};
int err = 0;
if(sockid <= 0 ) return false ;
err = recv(sockid, msg, sizeof(msg), MSG_PEEK);
/* client already close connection. */
if(err < 0 && (errno == EPIPE || errno == EBADF || errno == ECONNRESET))
return false;
return true;
}
int TTcpSocket::tcpSetlinger(int sockid)
{
struct linger lingerStruct={1,0};
if(setsockopt(sockid, SOL_SOCKET, SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct)) == -1)
return -1;
return 0;
}
int TTcpSocket::tcpSetNodelay(int sockid)
{
int nodelay = 1;
#ifdef TCP_NODELAY
if(setsockopt(sockid, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)) == -1)
return -1;
#endif
return 0;
}
// 连接TCP 服务器
int TTcpSocket::tcpConnect(const char *pszIP, short port, int iTimeout)
{
int iRet = -1, sockid=-1;
struct sockaddr_in addr;
int on = 1;
if(!pszIP || !((unsigned int)port > 1024 && (unsigned int)port < 65535)) {
vPrtLogMsg(LOG_ERROR, ErrSockParam, "in parameter ip/port %s:%d(1024-65535) invalid.", pszIP, port);
return ErrSockParam;
}
// Create socket
sockid = socket(AF_INET, SOCK_STREAM, 0);
if(sockid < 0 )
{
vPrtLogMsg (LOG_ERROR, errno, "create socket failed! errno[%d],msg:%s", errno,strerror(errno));
sockid = -1;
return sockid; // break;
}
memset(&addr, 0x00, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(pszIP); //htoni(INADDR_ANY);
/* set socket options */
#ifdef _WIN32
//setsockopt(sockid, SOL_SOCKET, SO_ERROR, (const char*)&on, sizeof(int));
if(setsockopt(sockid, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(int)) < 0) {
#else
if(setsockopt(sockid, SOL_SOCKET, SO_REUSEADDR, (const void*)&on, sizeof(int)) < 0) {
#endif
vPrtLogMsg (LOG_ERROR, errno, "setsockopt error! errno[%d],msg:%s", errno,strerror(errno));
tcpCloseSocket(sockid);
sockid = -1;
return sockid; // break;
}
//SetSocketMode(sockid); // 将建立的新连接置为非阻塞
iRet = connect(sockid, (struct sockaddr *)&addr, sizeof(addr));
if (iRet == 0) {
tcpSetlinger(sockid); // 建链成功
SetSocketMode(sockid); // 将建立的新连接置为非阻塞
return sockid;
}
tcpCloseSocket(sockid);
sockid = -1;
return sockid;
}
void TTcpSocket::clear_tcp_buffer(int socket_fd, int nbytes)
{
char buffer[MAX_TEMP_BUFFER_SIZE]={0};
int recv_len;
int i;
if(nbytes == 0) return ; // 如果需要清除的字节数为0 则直接返回成功
for(i = 0; i < (int)(nbytes / MAX_TEMP_BUFFER_SIZE); i++) {
recv_len = recv(socket_fd, buffer, MAX_TEMP_BUFFER_SIZE, 0);
if(recv_len >= 0 && recv_len < MAX_TEMP_BUFFER_SIZE) { // 期间如果发现缓冲区的数据已经被清空了则返回
return ;
}
else if(recv_len < 0) { // 异常了
return ;
}
}
recv_len = recv(socket_fd, buffer, (nbytes % MAX_TEMP_BUFFER_SIZE), 0);
if(recv_len >= 0) return ;
else return ;
}

@ -0,0 +1,114 @@
/****************************************************************************
** File name : HTThread.h
** Description : define server worker thread group
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyrigth By: xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
#include "HTThread.h"
static const char *_FILE_ ="HTThread.cpp";
/********************************************************************
* function : 线
* param in : none
* param out : None
* return val: 0 -- successed
* : <0 -- failed
********************************************************************/
static int HTNewThreadHandle(pthread_t **pThreadHandle, int thread_count)
{
*pThreadHandle = (pthread_t*)calloc(1, sizeof(pthread_t)*thread_count);
if(*pThreadHandle == NULL) {
vPrtLogMsg(LOG_ERROR, errno, "calloc for thread handle failed.");
return -1;
}
memset(*pThreadHandle, 0xff, sizeof(pthread_t)*thread_count);
return 0;
}
// 释放系统线程句柄
static int HTDelThreadHandle(pthread_t **pThreadHandle)
{
if(*pThreadHandle) {
free(*pThreadHandle);
*pThreadHandle = NULL;
}
return 0;
}
// 释放句柄
void HTFreeThreadHandle(void)
{
//HTDelThreadHandle(&thread_handle_recv);
//HTDelThreadHandle(&thread_handle_parse);
//HTDelThreadHandle(&thread_handle_setdb);
//HTDelThreadHandle(&thread_handle_respone);
}
/********************************************************************
* function : 线
* param in : none
* param out : None
* return val: 0 -- successed
* : <0 -- failed
********************************************************************/
int HTInitThreadHandle(void)
{
// if(HTNewThreadHandle(&thread_handle_recv,g_TConfig.getRecvThreadNumber()) != RET_OK) {
// HTFreeThreadHandle();
// return RET_FAIL;
// }
// if(HTNewThreadHandle(&thread_handle_parse,g_TConfig.getParseThreadNumber()) != RET_OK) {
// HTFreeThreadHandle();
// return RET_FAIL;
// }
//if(HTNewThreadHandle(&thread_handle_setdb,g_TConfig.getOprationThreadNumber()) != RET_OK) {
// HTFreeThreadHandle();
// return RET_FAIL;
//}
// if(HTNewThreadHandle(&thread_handle_respone,g_TConfig.getResponeThreadNumber()) != RET_OK) {
// HTFreeThreadHandle();
// return RET_FAIL;
// }
return 0;
}
/********************************************************************
* function : 线
* param in : none
* param out : None
* return val: 0 -- successed
* : <0 -- failed
********************************************************************/
int ht_pthread_create_background(pthread_t *thread_handle, void *(*pfunc)(void *), void *data)
{
#ifdef _WIN32
HANDLE handle = NULL;
handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pfunc,(LPVOID)data, 0, thread_handle);
if (!handle) {
::CloseHandle(handle);
return -1 ;
}
#else
if(pthread_create(thread_handle, NULL, pfunc, data) !=0 ) {
return -1 ;
}
#endif
return 0 ;
}
void pthread_testcancels(void)
{
#ifndef _WIN32
pthread_testcancel();
#endif
}

@ -0,0 +1,123 @@
/****************************************************************************
** File name : HTUnit.cpp
** Description : units changes for API
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
static const char *_FILE_ = "HTUnit.cpp" ;
//1:kV(千伏) 2 : V(伏) 3 : kA(千安) 4 : A(安) 5 : mA(毫安) 6 : ℃(度) 7 : Pa(帕) 8 : KPa(千帕) 9 : MPa(兆帕) 10 : pF(皮法-电容单位)
//11 : pC(皮库仑-电量单位) 12 : dB(分贝) 13 : μL(微升) 14 : mL(毫升) 15 : L(升) 16 : m / s(米 / 秒) 17 : rpm&r / min(转 / 分钟)
// 单位转换
double getChangeUnit(short Unit, short sysUnit, double val)
{
double retval = val;
switch (Unit)
{
case 1: // kV
if (sysUnit == 2) {
retval = val * 1000;
}
break;
case 2: // V
if (sysUnit == 1) {
retval = val / 1000;
}
break;
case 3: // kA
if (sysUnit == 4) { //A
retval = val * 1000;
}
else if (sysUnit == 5) { // mA
retval = val * 1000 * 1000;
}
break;
case 4: // A
if (sysUnit == 3) { //kA
retval = val / 1000;
}
else if (sysUnit == 5) { // mA
retval = val * 1000 ;
}
break;
case 5: // mA
if (sysUnit == 3) { //kA
retval = val / 1000 / 1000;
}
else if (sysUnit == 4) { // A
retval = val / 1000;
}
break;
case 6: //摄氏度
//if (sysUnit == 26) ////华氏度
// retval = (val - 32 / 1.800f);
break;
case 7: //Pa
if (sysUnit == 8) //KPa
retval = (val / 1000 );
else if (sysUnit == 9) //MPa
retval = (val / 1000 / 1000);
break;
case 8: //KPa
if (sysUnit == 7) //Pa
retval = (val * 1000);
else if (sysUnit == 9) //MPa
retval = (val / 1000 );
break;
case 9: //MPa
if (sysUnit == 7) //Pa
retval = (val * 1000 * 1000);
else if (sysUnit == 8) //KPa
retval = (val * 1000);
break;
case 13: //μL
if (sysUnit == 14) // mL
retval = val / 1000;
else if (sysUnit == 15) // L
retval = val / 1000 / 1000;
break;
case 14: //mL
if (sysUnit == 13) // μL
retval = val * 1000;
else if (sysUnit == 15) // L
retval = val / 1000;
break;
case 15: //L
if (sysUnit == 13) // μL
retval = val * 1000 * 1000;
else if (sysUnit == 14) // mL
retval = val * 1000;
break;
default:;
}
return retval;
}
//11法拉(F) = 1000毫法(mF)
//
//21毫法(mF) = 1000微法(μF)
//
//31微法(μF) = 1000纳法(nF)
//
//41纳法(nF) = 1000皮法(pF)
// 比较double之差是否大于rate.
// return : > true <= : false
bool bCompare(double ov, double nv, double rate)
{
if(rate <= 0.0f) return false;
double d= ((abs(nv - ov) / ov) * 100);
return d > rate ? true : false;
}

@ -0,0 +1,912 @@
/****************************************************************************
** File name : HTConfig.cpp
** Description : config parameter
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************/
#include "HTGlobal.h"
#include "HXIec104.h"
void NsNetServerProcess(void);
static void NsIec104Process(void);
static void NsIec104Init(unsigned char Card,short Port);
static void NsIec104NetInit(void);
static void NsIec104Reset(void);
static void NsIec104ProcessFormatI(void);
static void NsIec104ProcessFormatS(void);
static void NsIec104ProcessFormatU(void);
static void NsIec104Interrogation(void);
static void NsIec104InterrogationGroup(void);
static void NsIec104InterrogationAll(void);
static void NsIec104ProcessYxGroup(unsigned char Group);
static void NsIec104ProcessYcGroup(unsigned char Group);
static void NsIec104ProcessCellGroup(unsigned char Group);
static void NsIec104ProcessTime(void);
static void NsIec104ProcessYkYt(void);
static void NsIec104ProcessPulse(void);
static void NsIec104DefaultGroup(unsigned char Group);
static void NsIec104ProcessPulseData(void);
static void NsIec104SendGroup(void);
static void NsIec104SendYkMessage(short Who,unsigned char Action);
static void NsIec104ReceiveYkReturn(void);
static void NsIec104SendYkSelectConfirm(void);
static void NsIec104SendYkExeConfirm(void);
static void NsIec104SendYkEscConfirm(void);
static unsigned char NsIec104SendCosSoe(void);
static void NsIec104InitYk(void);
static void NsIec104CycleCount(void);
static void NsIec104SendChangeYc(void);
/*
static void Iec104testCosSoe(void);
void debug104(void);
*/
static void NsIec104Init(unsigned char Card,short Port)
{
unsigned short i;
int Result;
// char Buff[32];
// char Ip0Buff[64],Ip0Route[64];
//// char Ip1Buff[64],Ip1Route[64];
NS_SYSTEM_DATA_MODE SysData;
NsIec104Struct.LinkState=NS_DISCONNECTED;
NsIec104Struct.NsNewSocketId=0;
// getforsecond(&NsIec104Struct.LinkValidTime);
NsIec104Struct.ReceiveIndex=0;
NsIec104Struct.ReceiveIndexLength=0;
NsIec104Struct.SendMeNumber=0;
NsIec104Struct.HasSendNumber=0;
NsIec104Struct.NeedSendNumber=0;
NsIec104Struct.LeftSendNumber=0;
NsIec104Struct.Card=Card;
NsIec104Struct.Port=Port;
NsIec104Struct.YkStartSign=OFF;
NsIec104Struct.Table=0;
NsIec104Struct.NetRunSign=OFF;
NsIec104Struct.SetNetSign=OFF;
// Result=ReadNsc200Ini("NsIec104","SetTimeFlag",Buff);
if(Result)
{
NsIec104Struct.SetTimeFlag=1;
}
for(i=0;i<NS_IEC104_USE_CYCLE;i++)
{
// getforsecond(&NsIec104Cycle[i].LastTime);
NsIec104Cycle[i].TimeNap= NsIec104Nap[i];
NsIec104Cycle[i].TimeSign=OFF;
}
for(i=0;i<NS_IEC104_MAX_YC;i++)
NsIec104Struct.YcNap[i]=5;
NsIec104Struct.YcChangeCycle=0;
// NsIec104Struct.TableNo = NsGetCommTable(Port);
// GetSysDataMode(NsIec104Struct.TableNo,&SysData);
/*NsIec104Struct.XYxNum = SysData.NsYxTableNumber;
NsIec104Struct.XYmNum = SysData.NsYmTableNumber;*/
NsIec104Struct.XYcNum = SysData.NsYcTableNumber;
NsIec104Struct.XYcCycleNum = (NsIec104Struct.XYcNum + NS_IEC104_ONCE_YC_COUNT - 1) / NS_IEC104_ONCE_YC_COUNT;
}
#if 0
static void NsIec104NetInit(void)
{
int Result;
char Buff[32];
char Ip0Buff[64],Ip0Route[64];
char Ip1Buff[64],Ip1Route[64];
NsTcpServerInit(NsIec104Struct.Card,NsIec104Struct.Port,"10.14.127.200");
switch(NsIec104Struct.Card)
{
case 0:
Result=ReadNsc200Ini("NsIec104","Route0Sign",Buff);
if(Result)
{
NsReadIpAddress("NsIec104","Route0Net",Ip0Buff);
NsReadIpAddress("NsIec104","Route0Ip",Ip0Route);
NsAddRoute(Ip0Buff,Ip0Route);
}
break;
case 1:
Result=ReadNsc200Ini("NsIec104","Route1Sign",Buff);
if(Result)
{
NsReadIpAddress("NsIec104","Route1Net",Ip1Buff);
NsReadIpAddress("NsIec104","Route1Ip",Ip1Route);
NsAddRoute(Ip1Buff,Ip1Route);
}
break;
default:
break;
}
}
static void NsIec104InitYk(void)
{
NsIec104Struct.YkStartSign=OFF;
NsIec104Struct.YkNowState=0xff;
NsIec104Struct.YkCellNumber=0xff;
NsIec104Struct.YkKgNumber=0xff;
}
void NsNetServerProcessv(void)
{
while(1)
{
taskDelay(88);
}
}
void NsNetServerProcess(void)
{
unsigned long Now,Nap;
unsigned short Card;
int Result;
char Buff[32];
Card=0;
Result=ReadNsc200Ini("NsTasks","NsServerCard",Buff);
if(Result)
{
Card=Result;
if(Card<=2&&Card>0)
{
Card-=1;
}
}
NsIec104Init(Card,2404);
for(;;)
{
NsIec104Struct.SystemState = NsGetSysParameter(NS_NSCC_STATE);
NsIec104Struct.NetRunSign = NsNetConfigState();
if(NsIec104Struct.NetRunSign==ON&&NsIec104Struct.SetNetSign==OFF&&NsIec104Struct.SystemState==DUTY)
{
NsIec104NetInit();
NsIec104Struct.SetNetSign=ON;
}
if(NsIec104Struct.NetRunSign==ON&&NsIec104Struct.SetNetSign==ON&&NsIec104Struct.SystemState==DUTY)
{
getforsecond(&Now);
Nap=DiffMsLong(Now,NsIec104Struct.LinkValidTime);
if(Nap>NS_IEC104_PERMIT_TIME)
{
NsIec104Struct.LinkState=NS_DISCONNECTED;
}
if(NsIec104Struct.YkStartSign==ON)
{
Nap=DiffMsLong(Now,NsIec104Struct.YkStartTime);
if(Nap>NS_IEC104_YK_PERMIT_TIME)
{
NsIec104InitYk();
}
}
if(NsIec104Struct.LinkState==NS_DISCONNECTED)
{
NsIec104Struct.NsNewSocketId=NsTcpConnect(NsIec104Struct.NsNewSocketId,NsIec104Struct.Card);
if(NsIec104Struct.NsNewSocketId>0)
{
NsIec104Struct.LinkState=NS_CONNECTED;
NsIec104Struct.SendMeNumber=0;
getforsecond(&NsIec104Struct.LinkValidTime);
}
else
{
/*NsIec104Init(NsIec104Struct.Card,NsIec104Struct.Port);*/
/* NsTcpServerInit(NsIec104Struct.Card,NsIec104Struct.Port,"10.14.8.23");*/
NsIec104Struct.LinkState=NS_DISCONNECTED;
NsIec104Reset();
taskDelay(866);
}
}
else
{
NsIec104Struct.ReceiveIndexLength=recv(NsIec104Struct.NsNewSocketId,&NsIec104Struct.ReceiveBuffer[NsIec104Struct.ReceiveIndex],198,0);
if(NsIec104Struct.ReceiveIndexLength>0)
{
NsIec104Struct.ReceiveLength+=NsIec104Struct.ReceiveIndexLength;
if(NsIec104Struct.ReceiveLength<NS_IEC104_RECEIVEBUFFER)
{
NsIec104Process();
}
else
{
NsIec104Reset();
}
/*
debug104();
Iec104testCosSoe();
*/
getforsecond(&NsIec104Struct.LinkValidTime);
}
NsIec104ReceiveYkReturn();
NsIec104SendGroup();
if(NsIec104Struct.LeftSendNumber==0)
{
NsIec104Struct.CosSign=NsIec104SendCosSoe();
if(NsIec104Struct.CosSign==0)
{
NsIec104SendChangeYc();
}
}
}
NsIec104CycleCount();
}
taskDelay(18);
}
}
static void NsIec104SendChangeYc(void)
{
unsigned short General,Index;
unsigned char *P;
unsigned short i,RealNumber;
short *Pyc,YcValue,YcNap;
float fYc;
Index=0;
NsIec104Struct.SendBuffer[Index++]=0x68;
NsIec104Struct.SendBuffer[Index++]=0x00;
RealNumber=(NsIec104Struct.SendMeNumber<<1);
P=(unsigned char *)&RealNumber;
NsIec104Struct.SendBuffer[Index++]=P[0]; /* send number */
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendMeNumber=(NsIec104Struct.SendMeNumber+1)%65535;
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[0]; /* receive number */
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[1];
NsIec104Struct.SendBuffer[Index++]=9; /* asdu type */
NsIec104Struct.SendBuffer[Index++]=0; /* information object count No 7 Byte */
/* REASONBYTE now is two */
NsIec104Struct.SendBuffer[Index++]=3; /* reason */
NsIec104Struct.SendBuffer[Index++]=0x0; /* reason */
NsIec104Struct.SendBuffer[Index++]=0x01;
NsIec104Struct.SendBuffer[Index++]=0x00;
/*
for(i=0;i<NS_IEC_104_ASDUADDRESSBYTE;i++)
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.CommonAsduAddress[i];
*/
NsIec104Struct.YcLibIndex=NsIec104Struct.YcChangeCycle*NS_IEC104_ONCE_YC_COUNT;
/*NsIec104Struct.YcChangeCycle=(NsIec104Struct.YcChangeCycle+1)%NS_IEC104_CHANGE_YC_CYCLE;*/
NsIec104Struct.YcChangeCycle=(NsIec104Struct.YcChangeCycle+1)%NsIec104Struct.XYcCycleNum;
NsIec104Struct.YcChangeCount=0;
switch(NsIec104Struct.Table)
{
case 0:
NsGetDd1Lib(NS_YC_DATA,NsIec104Struct.YcLibIndex,NsIec104Struct.DataBuff,NS_IEC104_ONCE_YC_COUNT);
break;
case 1:
NsGetDd2Lib(NS_YC_DATA,NsIec104Struct.YcLibIndex,NsIec104Struct.DataBuff,NS_IEC104_ONCE_YC_COUNT);
break;
case 2:
NsGetDd3Lib(NS_YC_DATA,NsIec104Struct.YcLibIndex,NsIec104Struct.DataBuff,NS_IEC104_ONCE_YC_COUNT);
break;
case 3:
NsGetDd4Lib(NS_YC_DATA,NsIec104Struct.YcLibIndex,NsIec104Struct.DataBuff,NS_IEC104_ONCE_YC_COUNT);
break;
}
for(i=0;i<NS_IEC104_ONCE_YC_COUNT;i++)
{
/*Pyc=(short *)&NsIec104Struct.DataBuff[2*i];
YcValue= *Pyc;
YcNap=YcValue-NsIec104Struct.YcLastValue[NsIec104Struct.YcLibIndex+i];
if(YcNap<0)
YcNap=NsIec104Struct.YcLastValue[NsIec104Struct.YcLibIndex+i]-YcValue;
if(YcNap>NsIec104Struct.YcNap[NsIec104Struct.YcLibIndex+i])
{
NsIec104Struct.YcChangeCount++;
NsIec104Struct.YcLastValue[NsIec104Struct.YcLibIndex+i]=YcValue;*/
/* Information Object Address Now Three Bytes */
General=0x701+NsIec104Struct.YcLibIndex+i;
P=(unsigned char *)&General;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=0;
/*fYc = YcValue * 1.0;
P=(unsigned char *)&fYc;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=P[2];
NsIec104Struct.SendBuffer[Index++]=P[3];*/
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.DataBuff[2*i];
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.DataBuff[2*i + 1];
NsIec104Struct.SendBuffer[Index++]=0x00; /*qds*/
/*}*/
}
/* Repair Length and Count*/
NsIec104Struct.SendBuffer[1]=Index-2;
NsIec104Struct.SendBuffer[7]=NsIec104Struct.YcChangeCount;
if(NsIec104Struct.YcChangeCount>0)
{/*
printf("\n Co=%d Ind=%dGe=%d",NsIec104Struct.YcChangeCount,NsIec104Struct.YcLibIndex,General);
*/
if((NsIec104Struct.SendLength=send(NsIec104Struct.NsNewSocketId,&NsIec104Struct.SendBuffer[0],Index,0x0))<0)
{
perror ("Client FirstWrite Error");
}
}
}
static void NsIec104SendGroup(void)
{
if(NsIec104Struct.NeedSendNumber>0&&NsIec104Struct.HasSendNumber<NS_IEC104_MAX_K)
{
/*
printf("\n GroupId=%d",NsIec104Struct.NsNewSocketId);
*/
if((NsIec104Struct.SendLength=send(NsIec104Struct.NsNewSocketId,&NsIec104Struct.GroupSendBuffer[NsIec104Struct.LeftSendNumber][0],NsIec104Struct.GroupSendLength[NsIec104Struct.LeftSendNumber],0x0))<0)
{
perror ("GRoup Erroe");
}
NsIec104Struct.LeftSendNumber++;
/*
printf("\n Send Group=%d",NsIec104Struct.SendLength);
*/
if(NsIec104Struct.LeftSendNumber>=NsIec104Struct.NeedSendNumber)
{
NsIec104Struct.HasSendNumber=0;
NsIec104Struct.NeedSendNumber=0;
NsIec104Struct.LeftSendNumber=0;
}
}
taskDelay(108);
}
static void NsIec104Process(void)
{
int i;
/* printf("r:");
for(i=0;i<NsIec104Struct.ReceiveLength;i++)
printf("%4x",NsIec104Struct.ReceiveBuffer[i]);
printf("\n");
*/
if(NsIec104Struct.ReceiveLength>=NS_IEC_104_MIN_LENGTH && NsIec104Struct.ReceiveBuffer[0]==NS_IEC_104_HEAD)
{
NsIec104Struct.FormatType=NsIec104Struct.ReceiveBuffer[2]&0x03;
if(NsIec104Struct.FormatType==0||NsIec104Struct.FormatType==2) /* I */
{
NsIec104ProcessFormatI();
}
else
{
if(NsIec104Struct.FormatType==1) /* S */
NsIec104ProcessFormatS();
else
{
if(NsIec104Struct.FormatType==3)/* U */
NsIec104ProcessFormatU();
}
}
NsIec104Reset();
}
}
static void NsIec104ProcessFormatI(void)
{
int i;
unsigned char *p;
unsigned short NoWay;
/*
printf("\nFormatI");
*/
NsIec104Struct.ApduLength=NsIec104Struct.ReceiveBuffer[1];
if(NsIec104Struct.ApduLength>NS_IEC_104_MIN_LENGTH)
{
NsIec104Struct.ReceiveHimNumber[0]=NsIec104Struct.ReceiveBuffer[2];
NsIec104Struct.ReceiveHimNumber[1]=NsIec104Struct.ReceiveBuffer[3];
NoWay=*(unsigned short *)&NsIec104Struct.ReceiveHimNumber[0];
NoWay>>=1;
NoWay+=1;
NoWay<<=1;
p=(unsigned char *)&NoWay;
NsIec104Struct.ReceiveHimNumber[0]=p[0];
NsIec104Struct.ReceiveHimNumber[1]=p[1];
NsIec104Struct.AsduType=NsIec104Struct.ReceiveBuffer[6];
for(i=0;i< NS_IEC_104_REASONBYTE;i++)
NsIec104Struct.TransmitReason[i]=NsIec104Struct.ReceiveBuffer[NS_STARTREASON+i];
for(i=0;i<NS_IEC_104_ASDUADDRESSBYTE;i++)
NsIec104Struct.CommonAsduAddress[i]=NsIec104Struct.ReceiveBuffer[NS_STARTASDUADDRESS+i];
for(i=0;i<NS_IEC_104_INFORMATIONBYTE;i++)
NsIec104Struct.InformationObject[i]=NsIec104Struct.ReceiveBuffer[NS_STARTINFORMATION+i];
NsIec104Struct.AsduQualifier=NsIec104Struct.ReceiveBuffer[NS_STARTQUALIFIER];
switch(NsIec104Struct.AsduType)
{
case 46:
case 47:
NsIec104Struct.YkYtType=NsIec104Struct.AsduType;
NsIec104ProcessYkYt();
break;
case 100: /* Interrogation */
NsIec104Interrogation();
break;
case 101:
NsIec104ProcessPulse();
break;
case 103:
NsIec104ProcessTime();
/*
printf("\n Time1");
*/
break;
default:
break;
}
}
}
static unsigned char NsIec104SendCosSoe(void)
{
unsigned short Number;
NS_SOE_FORMAT SoeData;
NS_COS_FORMAT CosData;
unsigned short Index,SendCount;
unsigned char *P,i,CosSendSign;
unsigned short RealNumber,Object,Msecond;
Index=0;
CosSendSign=0;
Number=NsCheckDd1Cos();
if(Number>0)
{
if(Number>36)
Number=36;
SendCount=0;
Index=0;
NsIec104Struct.SendBuffer[Index++]=0x68;
NsIec104Struct.SendBuffer[Index++]=0x00;
RealNumber=(NsIec104Struct.SendMeNumber<<1);
P=(unsigned char *)&RealNumber;
NsIec104Struct.SendBuffer[Index++]=P[0]; /* send number */
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendMeNumber=(NsIec104Struct.SendMeNumber+1)%65535;
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[0]; /* receive number */
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[1];
NsIec104Struct.SendBuffer[Index++]=0x01; /* 0x01--->0x02 asdu type */
NsIec104Struct.SendBuffer[Index++]=1; /* information object count */
/* REASONBYTE now is two */
NsIec104Struct.SendBuffer[Index++]=0x03; /* reason */
NsIec104Struct.SendBuffer[Index++]=0x00; /* reason */
for(i=0;i<NS_IEC_104_ASDUADDRESSBYTE;i++)
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.CommonAsduAddress[i];
for(i=0;i<Number;i++)
{
if(NsGetDd1CosLib(&CosData)==ON)
{
SendCount++;
/* Information Object Address now three byte: 0xc01---0xc80 */
Object=CosData.SendNumber+0x01;
P=(unsigned char *)&Object;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=0x00;
NsIec104Struct.SendBuffer[Index++]=CosData.State;
}
}
/* Repair Length */
NsIec104Struct.SendBuffer[7]=SendCount; /* vsq number */
NsIec104Struct.SendBuffer[1]=Index-2;
}
else
{
Number=NsCheckDd1Soe();
if(Number>0)
{
if(Number>18)
Number=18;
SendCount=0;
Index=0;
NsIec104Struct.SendBuffer[Index++]=0x68;
NsIec104Struct.SendBuffer[Index++]=0x00;
RealNumber=(NsIec104Struct.SendMeNumber<<1);
P=(unsigned char *)&RealNumber;
NsIec104Struct.SendBuffer[Index++]=P[0]; /* send number */
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendMeNumber=(NsIec104Struct.SendMeNumber+1)%65535;
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[0]; /* receive number */
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[1];
NsIec104Struct.SendBuffer[Index++]=30; /* asdu type */
NsIec104Struct.SendBuffer[Index++]=1; /* information object count */
/* REASONBYTE now is two */
NsIec104Struct.SendBuffer[Index++]=0x03; /* reason */
NsIec104Struct.SendBuffer[Index++]=0x00; /* reason */
for(i=0;i<NS_IEC_104_ASDUADDRESSBYTE;i++)
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.CommonAsduAddress[i];
for(i=0;i<Number;i++)
{
if(NsGetDd1SoeLib(&SoeData)==ON)
{
SendCount++;
/* Information Object Address now three byte: 0xc01---0xc80 */
Object=SoeData.SendNumber+0x01;
P=(unsigned char *)&Object;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=0x00;
NsIec104Struct.SendBuffer[Index++]=SoeData.State;
Msecond=SoeData.Msecond+SoeData.Second*1000;
P=(unsigned char *)&Msecond;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=SoeData.Minute;
NsIec104Struct.SendBuffer[Index++]=SoeData.Hour;
NsIec104Struct.SendBuffer[Index++]=SoeData.Day;
NsIec104Struct.SendBuffer[Index++]=SoeData.Month;
NsIec104Struct.SendBuffer[Index++]=(SoeData.Year-2000);
}
}
/* Repair Length */
NsIec104Struct.SendBuffer[7]=SendCount; /* vsq number */
NsIec104Struct.SendBuffer[1]=Index-2;
}
else
{
if(NsIec104Cycle[0].TimeSign== ON)
{
Index=0;
NsIec104Struct.SendBuffer[Index++]=0x68;
NsIec104Struct.SendBuffer[Index++]=0x04;
NsIec104Struct.SendBuffer[Index++]=0x43;
NsIec104Struct.SendBuffer[Index++]=0x00;
NsIec104Struct.SendBuffer[Index++]=0x00;
NsIec104Struct.SendBuffer[Index++]=0x00;
NsIec104Cycle[0].TimeSign=OFF;
}
}
}
if(Index>0)
{
NsIec104Struct.SendLength=send(NsIec104Struct.NsNewSocketId,&NsIec104Struct.SendBuffer[0],Index,0x0);
CosSendSign=0x01;
}
return CosSendSign;
}
static void NsIec104ProcessYkYt(void)
{
unsigned char YkInformation,YkReason,YkWhat;
unsigned short YkObject;
unsigned char Media,YkAction;
NS_RELATION Dear;
/*
Information Object Address 0xb01---0xb80
for(i=0;i< NS_IEC_104_REASONBYTE;i++)
NsIec104Struct.TransmitReason[i]=NsIec104Struct.ReceiveBuffer[NS_STARTREASON+i];
for(i=0;i<NS_IEC_104_INFORMATIONBYTE;i++)
NsIec104Struct.InformationObject[i]=NsIec104Struct.ReceiveBuffer[NS_STARTINFORMATION+i];
*/
YkInformation=NsIec104Struct.ReceiveBuffer[NS_STARTINFORMATION+NS_IEC_104_INFORMATIONBYTE];
YkReason=NsIec104Struct.ReceiveBuffer[NS_STARTREASON];
YkObject=NsIec104Struct.ReceiveBuffer[NS_STARTINFORMATION]+NsIec104Struct.ReceiveBuffer[NS_STARTINFORMATION+1]*256;
YkObject-=0xb01;
YkWhat=0; /* nothing */
if(YkReason==6)
{
if(YkInformation&0x80) /* YkSelect */
YkWhat=1;
else
YkWhat=2; /* YkExe*/
}
else
if(YkReason==8) /* Esc*/
YkWhat=3;
switch(YkWhat)
{
case 1: /* select */
NsIec104Struct.ReceiveYkId=YkObject;
YkAction=YkInformation&0x03;
switch(YkAction)
{
case 1: /* Open */
NsIec104Struct.YkCellAction=NS_TRIP;
break;
case 2: /* close */
NsIec104Struct.YkCellAction=NS_CLOSE;
break;
default:
break;
}
NsIec104Struct.YkCellNumber=NsGetYkCell(NS_YK_CELL_NUMBER,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkKgNumber=NsGetYkCell(NS_YK_CELL_KG,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkNowState=NS_YK_SELECT;
Media=NsGetYkCell(NS_YK_CELL_CPU,NsIec104Struct.ReceiveYkId);
Dear.NsYkPort=NsIec104Struct.Card+NS_IEC_104_YK_BASE_PORT;
Dear.NsYkSlavePort=Media;
NsPutDear(&Dear,6);
NsIec104SendYkMessage(NS_YK_SELECT,NsIec104Struct.YkCellAction);
NsIec104Struct.YkStartSign=ON;
getforsecond(&NsIec104Struct.YkStartTime);
/*
printf("\n Send Yk SelectId=%d Cell=%d Kg=%d",NsIec104Struct.ReceiveYkId,NsIec104Struct.YkCellNumber,NsIec104Struct.YkKgNumber);
*/
break;
case 2: /* YkExe */
NsIec104Struct.ReceiveYkId=YkObject;
YkAction=YkInformation&0x03;
switch(YkAction)
{
case 1: /* Open */
NsIec104Struct.YkCellAction=NS_TRIP;
break;
case 2: /* close */
NsIec104Struct.YkCellAction=NS_CLOSE;
break;
default:
NsIec104Struct.YkCellAction=0xff;
break;
}
NsIec104Struct.YkCellNumber=NsGetYkCell(NS_YK_CELL_NUMBER,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkKgNumber=NsGetYkCell(NS_YK_CELL_KG,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkNowState=NS_YK_EXE;
Media=NsGetYkCell(NS_YK_CELL_CPU,NsIec104Struct.ReceiveYkId);
Dear.NsYkPort=NsIec104Struct.Card+NS_IEC_104_YK_BASE_PORT;
Dear.NsYkSlavePort=Media;
NsPutDear(&Dear,6);
NsIec104SendYkMessage(NS_YK_EXE,NsIec104Struct.YkCellAction);
NsIec104Struct.YkStartSign=ON;
getforsecond(&NsIec104Struct.YkStartTime);
/*
printf("\n Send Yk ExeId=%d Cell=%d Kg=%d",NsIec104Struct.ReceiveYkId,NsIec104Struct.YkCellNumber,NsIec104Struct.YkKgNumber);
*/
break;
case 3:
NsIec104Struct.ReceiveYkId=YkObject;
YkAction=YkInformation&0x03;
switch(YkAction)
{
case 1: /* Open */
NsIec104Struct.YkCellAction=NS_TRIP;
break;
case 2: /* close */
NsIec104Struct.YkCellAction=NS_CLOSE;
break;
default:
NsIec104Struct.YkCellAction=0xff;
break;
}
NsIec104Struct.YkCellNumber=NsGetYkCell(NS_YK_CELL_NUMBER,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkKgNumber=NsGetYkCell(NS_YK_CELL_KG,NsIec104Struct.ReceiveYkId);
NsIec104Struct.YkNowState=NS_YK_ESC;
Media=NsGetYkCell(NS_YK_CELL_CPU,NsIec104Struct.ReceiveYkId);
Dear.NsYkPort=NsIec104Struct.Card+NS_IEC_104_YK_BASE_PORT;
Dear.NsYkSlavePort=Media;
NsPutDear(&Dear,6);
NsIec104SendYkMessage(NS_YK_ESC,NsIec104Struct.YkCellAction);
NsIec104Struct.YkStartSign=ON;
getforsecond(&NsIec104Struct.YkStartTime);
/*
printf("\n Send Yk EscId=%d Cell=%d Kg=%d",NsIec104Struct.ReceiveYkId,NsIec104Struct.YkCellNumber,NsIec104Struct.YkKgNumber);
*/
break;
default:
break;
}
}
static void NsIec104SendYkMessage(short Who,unsigned char Action)
{
char Dd1Message[16];
switch(Who)
{
case NS_YK_ESC:
Dd1Message[0]=SEND_YK_HOST_DD1;
Dd1Message[1]=NS_YK_ESC;
Dd1Message[2]=NsIec104Struct.YkCellNumber;
Dd1Message[3]=NsIec104Struct.YkKgNumber;
Dd1Message[4]=NsIec104Struct.YkCellAction;
NsHostSendYkMessage(SEND_YK_HOST_DD1,8,Dd1Message);
break;
case NS_YK_EXE:
Dd1Message[0]=SEND_YK_HOST_DD1;
Dd1Message[1]=NS_YK_EXE;
Dd1Message[2]=NsIec104Struct.YkCellNumber;
Dd1Message[3]=NsIec104Struct.YkKgNumber;
Dd1Message[4]=NsIec104Struct.YkCellAction;
NsHostSendYkMessage(SEND_YK_HOST_DD1,8,Dd1Message);
break;
case NS_YK_SELECT:
Dd1Message[0]=SEND_YK_HOST_DD1;
Dd1Message[1]=NS_YK_SELECT;
Dd1Message[2]=NsIec104Struct.YkCellNumber;
Dd1Message[3]=NsIec104Struct.YkKgNumber;
Dd1Message[4]=NsIec104Struct.YkCellAction;
NsHostSendYkMessage(SEND_YK_HOST_DD1,8,Dd1Message);
break;
}
}
static void NsIec104ReceiveYkReturn(void)
{
char ReturnMessage[16];
int Length,HasMessage;
NS_RELATION Dear;
if(NsIec104Struct.YkStartSign==ON)
{
NsGetDear(&Dear);
if(Dear.NsYkPort==(NsIec104Struct.Card+NS_IEC_104_YK_BASE_PORT))
{
/*
printf("\n Yk Return");
*/
if(NsHostReceiveYkMessage(SEND_YK_HOST_DD1,ReturnMessage)==1)
{
/*
printf("\nYkMes0=%0x--1=%0x--2=%0x---3=%0x---4=%0x",
ReturnMessage[0],ReturnMessage[1],ReturnMessage[2],ReturnMessage[3],ReturnMessage[4]);
*/
if(ReturnMessage[0]==SEND_YK_HOST_DD1)
{
if(NsIec104Struct.YkNowState==ReturnMessage[1])
{
if((ReturnMessage[2]==NsIec104Struct.YkCellNumber)&&
(ReturnMessage[3]==NsIec104Struct.YkKgNumber)&&
(ReturnMessage[4]==NsIec104Struct.YkCellAction))
{
NsIec104Struct.YkError=ReturnMessage[5];
if(NsIec104Struct.YkNowState==NS_YK_SELECT)
{
NsIec104SendYkSelectConfirm();
/*
printf("\n Selec Confim");
*/
}
else
{
if(NsIec104Struct.YkNowState==NS_YK_EXE)
NsIec104SendYkExeConfirm();
else
{
if(NsIec104Struct.YkNowState==NS_YK_ESC)
NsIec104SendYkEscConfirm();
}
}
}
}
}
}
}
}
}
static void NsIec104SendYkSelectConfirm(void)
{
unsigned short YkObject,Index;
unsigned char *P,i;
unsigned short RealNumber;
Index=0;
NsIec104Struct.SendBuffer[Index++]=0x68;
NsIec104Struct.SendBuffer[Index++]=0x00;
RealNumber=(NsIec104Struct.SendMeNumber<<1);
P=(unsigned char *)&RealNumber;
NsIec104Struct.SendBuffer[Index++]=P[0]; /* send number */
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendMeNumber=(NsIec104Struct.SendMeNumber+1)%65535;
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[0]; /* receive number */
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.ReceiveHimNumber[1];
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.YkYtType; /* asdu type */
NsIec104Struct.SendBuffer[Index++]=1; /* information object count */
/* REASONBYTE now is two */
NsIec104Struct.SendBuffer[Index++]=0x07; /* reason */
NsIec104Struct.SendBuffer[Index++]=0x00; /* reason */
for(i=0;i<NS_IEC_104_ASDUADDRESSBYTE;i++)
NsIec104Struct.SendBuffer[Index++]=NsIec104Struct.CommonAsduAddress[i];
/* Information Object Address now three byte: 0xc01---0xc80 */
YkObject=NsIec104Struct.ReceiveYkId+0xb01;
P=(unsigned char *)&YkObject;
NsIec104Struct.SendBuffer[Index++]=P[0];
NsIec104Struct.SendBuffer[Index++]=P[1];
NsIec104Struct.SendBuffer[Index++]=0x00;
/* Value */
if(NsIec104Struct.YkCellAction==NS_TRIP)
NsIec104Struct.SendBuffer[Index++]=0x81;
else
if(NsIec104Struct.YkCellAction==NS_CLOSE)
NsIec104Struct.SendBuffer[Index++]=0x82;
else

@ -0,0 +1,59 @@
#############################################################################
# HTService project makefile
#
# 说明:
# CFLAGS: 宏BIG_ENDIAN在Sun Solaris下必须设定,而在Linux系统下不能设定此宏.
# LIBS : 在Sun Solaris下必须指定库"-lsocket",在Linux下必须去除该库.
#
#############################################################################
# flags
CC = g++
CFLAGS = -Wall
LFLAGS =
# args
RELEASE =0
BITS =
# [args] 生成模式. 0代表debug模式, 1代表release模式. make RELEASE=1.
ifeq ($(RELEASE),0)
# debug
CFLAGS += -g
else
# release
CFLAGS += -static -O3 -DNDEBUG
LFLAGS += -static
endif
# [args] 程序位数. 32代表32位程序, 64代表64位程序, 其他默认. make BITS=32.
ifeq ($(BITS),32)
CFLAGS += -m32
LFLAGS += -m32
else
ifeq ($(BITS),64)
CFLAGS += -m64
LFLAGS += -m64
else
endif
endif
.PHONY : all clean
# files
TARGETS = gcc64_make
OBJS = gcc64_make.o
all : $(TARGETS)
gcc64_make : $(OBJS)
$(CC) $(LFLAGS) -o $@ $^
gcc64_make.o : gcc64_make.c
$(CC) $(CFLAGS) -c $<
clean :
rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))

@ -0,0 +1,50 @@
#############################################################################
# HTService project makefile
#
# 说明:
# CFLAGS: 宏BIG_ENDIAN在Sun Solaris下必须设定,而在Linux系统下不能设定此宏.
# LIBS : 在Sun Solaris下必须指定库"-lsocket",在Linux下必须去除该库.
#
#############################################################################
CC = g++
MYSQL_PATH = /usr/local/mysql-5.5.61
MYSQL_LIB_FILE = mysqlclient
#CFLAGS = -c -Werror -g -D_REENTRANT -Wformat -Wsign-compare -O3 -ansi
CFLAGS = -c -Werror -g -D_DEBUG -D_REENTRANT -Wformat -Wsign-compare -O3 -ansi
LIBS = -L$(MYSQL_PATH)/lib -l$(MYSQL_LIB_FILE) `pkg-config --libs opencv` -lnsl -lpthread -lm -lc -lstdc++
INCPATH = -I../include -I$(MYSQL_PATH)/include `pkg-config --cflags opencv`
# global file
OBJS_PATH = ../obj
OBJS = $(OBJS_PATH)/HTService.o $(OBJS_PATH)/HTGlobal.o \
$(OBJS_PATH)/HTPublic.o $(OBJS_PATH)/HTThread.o \
$(OBJS_PATH)/HTInitUtils.o $(OBJS_PATH)/HTLogger.o \
$(OBJS_PATH)/HTDatabase.o $(OBJS_PATH)/HTTcpSocket.o \
$(OBJS_PATH)/HTConfig.o $(OBJS_PATH)/HTIEC104.o \
$(OBJS_PATH)/NsIec104Server.o $(OBJS_PATH)/HTCP56Time2a.o \
$(OBJS_PATH)/HTOpencvImg.o $(OBJS_PATH)/HTTestOpencv.o
TARGET = ../bin/HTService
# for link
$(TARGET):$(OBJS)
$(CC) -Wall -O3 -o $(TARGET) $(OBJS) $(LIBS)
$(OBJS_PATH)/%.o : ./%.cpp
$(CC) $(CFLAGS) $(INCPATH) $< -o $@
$(OBJS_PATH)/%.o : ./compress/%.c
cc $(CFLAGS) $(INCPATH) $< -o $@
################################################################
# clean flag str....
clean:
rm -rf $(OBJS_PATH)/*.o ../bin/core.* ../log/*.log $(TARGET)
log :
rm -rf ../log/*.log ../bin/core.*
obj:
rm -rf $(OBJS_PATH)/*.o

@ -0,0 +1,55 @@
#############################################################################
# HTService project makefile
#
# 说明:
# CFLAGS: 宏BIG_ENDIAN在Sun Solaris下必须设定,而在Linux系统下不能设定此宏.
# LIBS : 在Sun Solaris下必须指定库"-lsocket",在Linux下必须去除该库.
#
#############################################################################
CC = g++
#MYSQL_PATH = /usr/local/mysql-5.5.43
MYSQL_PATH = /usr/local/mysql-5.7.28
MYSQL_LIB_FILE = mysqlclient
#CFLAGS = -c -Werror -g -D_REENTRANT -Wformat -Wsign-compare -O3 -ansi
CFLAGS = -c -Werror -g -D_DEBUG -D_REENTRANT -Wformat -Wsign-compare -O3 -ansi
LIBS = -L$(MYSQL_PATH)/lib -l$(MYSQL_LIB_FILE) `pkg-config --libs opencv` -lnsl -luuid -lpthread -lm -lc -lstdc++
INCPATH = -I../include -I$(MYSQL_PATH)/include `pkg-config --cflags opencv`
# global file
OBJS_PATH = ../obj
OBJS = $(OBJS_PATH)/HTService.o $(OBJS_PATH)/HTGlobal.o \
$(OBJS_PATH)/HTPublic.o $(OBJS_PATH)/HTThread.o \
$(OBJS_PATH)/HTInitUtils.o $(OBJS_PATH)/HTLogger.o \
$(OBJS_PATH)/HTDatabase.o $(OBJS_PATH)/HTTcpSocket.o \
$(OBJS_PATH)/HTConfig.o $(OBJS_PATH)/HTIEC104.o \
$(OBJS_PATH)/HXIec104.o $(OBJS_PATH)/HTCP56Time.o \
$(OBJS_PATH)/HTImageBusi.o $(OBJS_PATH)/HTMemCacheData.o \
$(OBJS_PATH)/HTOpencvImg.o $(OBJS_PATH)/HTUnit.o
# $(OBJS_PATH)/HTTestOpencv.o
TARGET = ../bin/iecserver
#TARGET = ../bin/IMGService
# for link
$(TARGET):$(OBJS)
$(CC) -Wall -O3 -o $(TARGET) $(OBJS) $(LIBS)
$(OBJS_PATH)/%.o : ./%.cpp
$(CC) $(CFLAGS) $(INCPATH) $< -o $@
$(OBJS_PATH)/%.o : ./compress/%.c
cc $(CFLAGS) $(INCPATH) $< -o $@
################################################################
# clean flag str....
clean:
rm -rf $(OBJS_PATH)/*.o ../bin/core.* ../log/*.log $(TARGET)
log :
rm -rf ../log/*.log ../bin/core.*
obj:
rm -rf $(OBJS_PATH)/*.o

@ -0,0 +1,59 @@
#############################################################################
# HTService project makefile
#
# 说明:
# CFLAGS: 宏BIG_ENDIAN在Sun Solaris下必须设定,而在Linux系统下不能设定此宏.
# LIBS : 在Sun Solaris下必须指定库"-lsocket",在Linux下必须去除该库.
#
#############################################################################
# flags
CC = g++
CFLAGS = -Wall
LFLAGS =
# args
RELEASE =0
BITS =
# [args] 生成模式. 0代表debug模式, 1代表release模式. make RELEASE=1.
ifeq ($(RELEASE),0)
# debug
CFLAGS += -g
else
# release
CFLAGS += -static -O3 -DNDEBUG
LFLAGS += -static
endif
# [args] 程序位数. 32代表32位程序, 64代表64位程序, 其他默认. make BITS=32.
ifeq ($(BITS),32)
CFLAGS += -m32
LFLAGS += -m32
else
ifeq ($(BITS),64)
CFLAGS += -m64
LFLAGS += -m64
else
endif
endif
.PHONY : all clean
# files
TARGETS = gcc64_make
OBJS = gcc64_make.o
all : $(TARGETS)
gcc64_make : $(OBJS)
$(CC) $(LFLAGS) -o $@ $^
gcc64_make.o : gcc64_make.c
$(CC) $(CFLAGS) -c $<
clean :
rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))
Loading…
Cancel
Save