1281 lines
49 KiB
C++
1281 lines
49 KiB
C++
#include "hostadsbf.h"
|
||
#include <array>
|
||
#include <math.h>
|
||
#include <ry.h>
|
||
|
||
#define MAX_BLOCKF_SIZE 512
|
||
#define DATA_BLOCK_BOUNDARY 400
|
||
|
||
#define REGISTER_DATA_TYPE_YC 1
|
||
#define REGISTER_DATA_TYPE_YM 2
|
||
#define REGISTER_DATA_TYPE_YX_BYTE 3
|
||
#define REGISTER_DATA_TYPE_YX_WORD 4
|
||
#define REGISTER_DATA_TYPE_YX_DWORD 5
|
||
|
||
#define ADSP_READ_ID 100 //读取文件及文件夹ID
|
||
#define ADSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。
|
||
#define ADSP_READ_ID_REGISTER_ADDRESS 300 //读取文件及文件夹ID寄存器地址。
|
||
#define ADSP_READ_ID_REGISTER_LENGTH 32 //读取文件及文件夹ID寄存器长度。
|
||
|
||
|
||
static datalen2mbaddrmap m_datalen2mbaddr_map;
|
||
static struDataLengthMBAddr m_datalen_mbaddr[] = {
|
||
{ 1, 400 },
|
||
{ 1, 402 },
|
||
{ 1, 404 },
|
||
{ 4, 421 },
|
||
{ 4, 409 },
|
||
{ 4, 445 },
|
||
{ 4, 659 },
|
||
{ 4, 663 },
|
||
{ 4, 425 },
|
||
{ 4, 413 },
|
||
{ 4, 449 },
|
||
{ 4, 429 },
|
||
{ 4, 417 },
|
||
{ 4, 453 },
|
||
{ 4, 683 },
|
||
{ 4, 643 },
|
||
{ 4, 647 },
|
||
{ 4, 651 },
|
||
{ 4, 711 },
|
||
{ 4, 655 },
|
||
{ 4, 715 },
|
||
{ 4, 703 },
|
||
{ 4, 707 },
|
||
{ 4, 457 },
|
||
{ 4, 461 },
|
||
{ 4, 493 },
|
||
{ 4, 497 },
|
||
{ 4, 501 },
|
||
{ 4, 433 },
|
||
{ 4, 437 },
|
||
{ 4, 441 },
|
||
{ 4, 687 },
|
||
{ 4, 691 },
|
||
{ 4, 695 },
|
||
{ 4, 517 },
|
||
{ 4, 465 },
|
||
{ 4, 469 },
|
||
{ 4, 473 },
|
||
{ 4, 477 },
|
||
{ 4, 481 },
|
||
{ 4, 485 },
|
||
{ 4, 489 },
|
||
{ 4, 675 },
|
||
{ 4, 679 },
|
||
{ 4, 505 },
|
||
{ 4, 509 },
|
||
{ 4, 513 },
|
||
{ 4, 667 },
|
||
{ 4, 671 },
|
||
{ 4, 2 },
|
||
{ 4, 6 },
|
||
{ 4, 10 },
|
||
{ 4, 14 },
|
||
{ 4, 18 },
|
||
{ 4, 22 },
|
||
{ 4, 26 },
|
||
{ 4, 30 },
|
||
{ 4, 34 },
|
||
{ 4, 38 },
|
||
{ 4, 42 },
|
||
{ 4, 46 },
|
||
{ 4, 50 },
|
||
{ 4, 54 },
|
||
{ 4, 58 },
|
||
{ 4, 62 },
|
||
{ 4, 66 },
|
||
{ 4, 70 },
|
||
{ 4, 74 },
|
||
{ 4, 78 },
|
||
{ 4, 82 },
|
||
{ 4, 86 },
|
||
{ 4, 90 },
|
||
{ 4, 94 },
|
||
{ 4, 98 },
|
||
{ 4, 102 },
|
||
{ 4, 106 },
|
||
{ 4, 110 },
|
||
{ 4, 114 },
|
||
{ 4, 118 },
|
||
{ 4, 122 },
|
||
{ 4, 126 },
|
||
{ 4, 130 },
|
||
{ 4, 134 },
|
||
{ 4, 138 },
|
||
{ 4, 142 },
|
||
{ 4, 146 },
|
||
{ 4, 150 },
|
||
{ 4, 154 },
|
||
{ 4, 158 },
|
||
{ 4, 162 },
|
||
{ 4, 166 },
|
||
{ 4, 170 },
|
||
{ 4, 174 },
|
||
{ 4, 178 },
|
||
{ 4, 182 },
|
||
{ 4, 186 },
|
||
{ 4, 190 },
|
||
{ 4, 194 },
|
||
{ 4, 198 },
|
||
{ 4, 202 },
|
||
{ 4, 206 },
|
||
{ 4, 210 },
|
||
{ 4, 214 },
|
||
{ 4, 218 },
|
||
{ 4, 222 },
|
||
{ 4, 226 },
|
||
{ 4, 230 },
|
||
{ 4, 234 },
|
||
{ 4, 238 },
|
||
{ 4, 242 },
|
||
{ 4, 246 },
|
||
{ 4, 250 },
|
||
{ 4, 254 },
|
||
{ 4, 258 },
|
||
{ 4, 262 },
|
||
{ 4, 266 },
|
||
{ 4, 270 },
|
||
{ 4, 274 },
|
||
{ 4, 521 },
|
||
{ 4, 525 },
|
||
{ 4, 537 },
|
||
{ 4, 533 },
|
||
{ 4, 545 },
|
||
{ 4, 541 },
|
||
{ 4, 699 },
|
||
{ 4, 639 },
|
||
{ 4, 631 },
|
||
{ 4, 635 },
|
||
{ 1, 407 },
|
||
{ 1, 406 },
|
||
{ 1, 408 },
|
||
{ 2, 549 },
|
||
{ 2, 551 },
|
||
{ 2, 553 },
|
||
{ 2, 555 },
|
||
{ 2, 557 },
|
||
{ 2, 559 },
|
||
{ 2, 561 },
|
||
{ 2, 563 },
|
||
{ 2, 565 },
|
||
{ 2, 567 },
|
||
{ 2, 569 },
|
||
{ 2, 571 },
|
||
{ 2, 573 },
|
||
{ 2, 575 },
|
||
{ 2, 577 },
|
||
{ 2, 579 },
|
||
{ 2, 581 },
|
||
{ 2, 583 },
|
||
{ 2, 585 },
|
||
{ 2, 587 },
|
||
{ 2, 589 },
|
||
{ 2, 591 },
|
||
{ 2, 593 },
|
||
{ 2, 595 },
|
||
{ 2, 597 },
|
||
{ 2, 599 },
|
||
{ 2, 601 },
|
||
{ 2, 611 },
|
||
{ 2, 603 },
|
||
{ 2, 609 },
|
||
{ 2, 613 },
|
||
{ 2, 615 },
|
||
{ 2, 617 },
|
||
{ 2, 619 },
|
||
{ 2, 623 }
|
||
};
|
||
|
||
|
||
static bool publish_sensor_data(const char* command, const Json::Value payload)
|
||
{
|
||
Json::StreamWriterBuilder builder;
|
||
builder["indentation"] = "";
|
||
builder["emitUTF8"] = true;
|
||
|
||
Json::Value jsonRoot;
|
||
jsonRoot["cmd"] = command;
|
||
|
||
char str[128];
|
||
#ifdef NOPOLL_64BIT_PLATFORM
|
||
snprintf(str, sizeof(str), "%ld", snowflake_next_id());
|
||
#else
|
||
snprintf(str, sizeof(str), "%lld", snowflake_next_id());
|
||
#endif
|
||
|
||
jsonRoot["cmdId"] = str;
|
||
|
||
Json::Int64 mtime = (Json::Int64)time(NULL);
|
||
mtime *= 1000;
|
||
jsonRoot["time"] = mtime;
|
||
jsonRoot["data"] = payload;
|
||
|
||
std::string outputConfig = Json::writeString(builder, jsonRoot);
|
||
g_conn->sendMsg(outputConfig);
|
||
|
||
return true;
|
||
}
|
||
|
||
static WORD GetUnitYCRegisterAddr(int uid, int point)
|
||
{
|
||
struUnit* pUnit;
|
||
struUnitYC* pYC;
|
||
|
||
if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535;
|
||
pUnit = &config.units[uid];
|
||
if (pUnit->yccount <= 0) return (WORD)65535;
|
||
if (point < 0 || point >= pUnit->yccount) return (WORD)65535;
|
||
pYC = &pUnit->ycs[point];
|
||
return (MAKEWORD(pYC->m_param[0], pYC->m_param[1]));
|
||
}
|
||
|
||
static WORD GetUnitYXRegisterAddr(int uid, int point)
|
||
{
|
||
struUnit* pUnit;
|
||
struUnitYX* pYX;
|
||
|
||
if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535;
|
||
pUnit = &config.units[uid];
|
||
if (pUnit->yxcount <= 0) return (WORD)65535;
|
||
if (point < 0 || point >= pUnit->yxcount) return (WORD)65535;
|
||
pYX = &pUnit->yxs[point];
|
||
return (MAKEWORD(pYX->m_param[0], pYX->m_param[1]));
|
||
}
|
||
|
||
static BYTE GetUnitYXDataPos(int uid, int point)
|
||
{
|
||
struUnit* pUnit;
|
||
struUnitYX* pYX;
|
||
|
||
if (uid < 0 || uid >= UNIT_NUM) return (BYTE)0;
|
||
pUnit = &config.units[uid];
|
||
if (pUnit->yxcount <= 0) return (BYTE)0;
|
||
if (point < 0 || point >= pUnit->yxcount) return (BYTE)0;
|
||
pYX = &pUnit->yxs[point];
|
||
return (pYX->m_param[3]);
|
||
}
|
||
|
||
static BOOLEAN GetYCValue(const int order, const FIELDDES* fields, const char* pData, LONG& value)
|
||
{
|
||
if (pData == NULL) return FALSE;
|
||
if (fields == NULL) return FALSE;
|
||
if (order < 0 || order >= (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0]))) return FALSE;
|
||
int start = fields[order].start;
|
||
if (fields[order].length == sizeof(DWORD))
|
||
{ //4字节
|
||
value = *(LONG *)(pData + start);
|
||
return TRUE;
|
||
}
|
||
else if (fields[order].length == sizeof(WORD))
|
||
{
|
||
short tmp = *(short *)(pData + start);
|
||
value = (LONG)tmp;
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
static BOOLEAN GetYXValue(const int order, const FIELDDES* fields, const char* pData, const int pos, BOOLEAN& value)
|
||
{
|
||
if (pData == NULL) return FALSE;
|
||
if (fields == NULL) return FALSE;
|
||
if (pos < 0 || pos >= 16) return FALSE;
|
||
if (order < 0 || order >= (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0]))) return FALSE;
|
||
int start = fields[order].start;
|
||
if (fields[order].length == sizeof(WORD))
|
||
{
|
||
WORD tmp = *(WORD *)(pData + start);
|
||
WORD nTemp = 0x0001;
|
||
nTemp <<= pos;
|
||
if (tmp & nTemp) value = TRUE;
|
||
else value = FALSE;
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
static bool publishhistoryHighSpeedData(const int uid, const QWORD dt, const Json::Value values)
|
||
{
|
||
if (uid < 0 || uid >= UNIT_NUM) return false;
|
||
Json::Value root;
|
||
if (values.size()) {
|
||
root["dataTime"] = (Json::Int64)dt;
|
||
root["deviceId"] = static_units[uid].deviceId;
|
||
root["values"] = values;
|
||
return publish_sensor_data("historyHighSpeedData", root);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
#ifndef USE_NOPOLL_WEBSOCKET
|
||
static bool publishhistoryLowSpeedData(const int uid, const QWORD dt, const Json::Value values)
|
||
#else
|
||
static bool publishhistoryLowSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values)
|
||
#endif
|
||
{
|
||
if (uid < 0 || uid >= UNIT_NUM) return false;
|
||
Json::Value root;
|
||
|
||
if (values.size()) {
|
||
root["dataTime"] = (Json::Int64)(dt / 1000 * 1000); //取整
|
||
root["deviceId"] = static_units[uid].deviceId;
|
||
root["values"] = values;
|
||
#ifndef USE_NOPOLL_WEBSOCKET
|
||
return publish_sensor_data("historyLowSpeedData", root);
|
||
#else
|
||
return publish_sensor_data(conn, "historyLowSpeedData", root);
|
||
#endif
|
||
}
|
||
return false;
|
||
}
|
||
|
||
#if 0
|
||
static int ftpget(const char* remote, const char* local, const char* user, const char* pwd, const long timeout = 3, struct memory* chunk = NULL)
|
||
{
|
||
//vLog(LOG_DEBUG, "start to get %s to local %s, with name: %s, and password: %s.\n", remote, local, user, pwd);
|
||
curl_global_init(CURL_GLOBAL_ALL);
|
||
CURL* curl = curl_easy_init();
|
||
|
||
char user_key[1024] = {0};
|
||
snprintf(user_key, sizeof(user_key), "%s:%s", user, pwd);
|
||
|
||
CURLcode ret = CURLE_GOT_NOTHING;
|
||
|
||
curl_easy_setopt(curl, CURLOPT_URL, remote);
|
||
curl_easy_setopt(curl, CURLOPT_USERPWD, user_key);
|
||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
|
||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)chunk);
|
||
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); // Optional: depending on your FTP server
|
||
ret = curl_easy_perform(curl);
|
||
|
||
curl_easy_cleanup(curl);
|
||
curl_global_cleanup();
|
||
|
||
return ret;
|
||
}
|
||
#endif
|
||
static void* ryftp_process(void* param)
|
||
{
|
||
if (param == NULL) return ((void*)0);
|
||
|
||
CHostADSBFProcess* mbt = (CHostADSBFProcess *)param;
|
||
|
||
//获取此协议配置里面的ftp信息
|
||
char remote[512];
|
||
//char name[512];
|
||
|
||
//默认参数,或是通过协议配置获取
|
||
char user[128] = "administrator";
|
||
char password[128] = "123456";
|
||
char ipaddress[128] = "127.0.0.1";
|
||
char remotePath[128] = "Hard Disk2/data/rtdatalog";
|
||
//char pathName[128] = "./";
|
||
|
||
char processName[128];
|
||
snprintf(processName, sizeof(processName), "%s", mbt->m_pidName.c_str());
|
||
//配置远方路径
|
||
char* escaped_string = escape_char_in_string(mbt->m_remotePath, ' ');
|
||
if (escaped_string == NULL)
|
||
{
|
||
vLog(LOG_DEBUG, "%s 路径转义错误!\n", processName);
|
||
return ((void*)0);
|
||
}
|
||
snprintf(remotePath, sizeof(remotePath), "%s", escaped_string);
|
||
free(escaped_string);
|
||
#if 0
|
||
//根据协议创s建一个本地协议目录
|
||
int pid = mbt->GetCurID();
|
||
if (pid < 0 || pid >= PROCESSES_NUM) return ((void*)0);
|
||
char pathName[128];
|
||
snprintf(pathName, sizeof(pathName), "%d", pid);
|
||
if (mbt->_mkdir(pathName) < 0) return ((void*)0);
|
||
#endif
|
||
//配置的用户名和密码
|
||
snprintf(user, sizeof(user), "%s", mbt->m_user);
|
||
snprintf(password, sizeof(password), "%s", mbt->m_password);
|
||
|
||
//配置ip地址
|
||
memset(ipaddress, '\0', sizeof(ipaddress));
|
||
snprintf(ipaddress, sizeof(ipaddress), "%s", mbt->getRemoteIp());
|
||
|
||
|
||
for (int i = 0; i < (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])); i++) {
|
||
m_datalen2mbaddr_map.insert(datalen2mbaddrmap::value_type(m_datalen_mbaddr[i].address, i + 1));
|
||
}
|
||
|
||
int len = 0;
|
||
//struRYDeviceData t_data;
|
||
FIELDDES fields[1024];
|
||
len = calcFields(fields);
|
||
|
||
//判断是否链接单元
|
||
int uid = mbt->GetUnitID(0); //默认只接一个设备
|
||
|
||
if (uid < 0 || uid >= UNIT_NUM) return ((void*)0);
|
||
|
||
datatypemap highspeedmap;
|
||
datatypemap lowspeedmap;
|
||
datatypeposmap yxdatamap;
|
||
|
||
int yccount = GetUnitYCCount(uid);
|
||
for (int i = 0; i < yccount; i++) {
|
||
//根据遥测参数配置寄存器,获取高频数据寄存器
|
||
WORD register_addr = GetUnitYCRegisterAddr(uid, i);
|
||
if (GetUnitYCType(uid, i)) {
|
||
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
|
||
highspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号,order-数据文件序号
|
||
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
|
||
}
|
||
} else {
|
||
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
|
||
lowspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号,order-数据文件序号
|
||
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
|
||
}
|
||
}
|
||
}
|
||
int yxcount = GetUnitYXCount(uid);
|
||
for (int i = 0; i < yxcount; i++) {
|
||
//根据遥测参数配置寄存器,获取高频数据寄存器
|
||
WORD register_addr = GetUnitYXRegisterAddr(uid, i);
|
||
BYTE data_pos = GetUnitYXDataPos(uid, i);
|
||
//vLog(LOG_DEBUG, "register_addr is: %d, pos is: %d.\n", register_addr, data_pos);
|
||
struDataPos pos;
|
||
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
|
||
pos.point = m_datalen2mbaddr_map[register_addr];
|
||
pos.pos = data_pos;
|
||
yxdatamap.insert(datatypeposmap::value_type(i, pos)); //point-配置的序号,order-数据文件序号
|
||
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
|
||
}
|
||
}
|
||
|
||
//根据实际配置表将
|
||
WORD ftpget_retry_count = 0;
|
||
BOOLEAN bReadCurrentFile = TRUE; //读取当前文件标识
|
||
|
||
while (TRUE) {
|
||
sleep(1); //每秒执行一次
|
||
if (!mbt->m_bFtpRun) break;
|
||
//ftp获取文件
|
||
if (mbt->m_iv == 1) {
|
||
//文件目录无效
|
||
continue;
|
||
}
|
||
|
||
if (bReadCurrentFile)
|
||
{ //读取当前文件
|
||
//vLog(LOG_DEBUG, "读取当前文件.\n");
|
||
//snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_currentFileNo);
|
||
snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_currentDirNo, mbt->m_currentFileNo);
|
||
}
|
||
else
|
||
{ //读取未读的文件
|
||
//vLog(LOG_DEBUG, "读取未读的文件.\n");
|
||
//snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_lastReadFileNo);
|
||
snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_lastReadDirNo, mbt->m_lastReadFileNo);
|
||
}
|
||
|
||
struct memory chunk = {0}; // For storing the downloaded data
|
||
//vLog(LOG_DEBUG, "start to read %s\n", remote);
|
||
CURLcode result = ftpget(remote, user, password, 3, &chunk);
|
||
//vLog(LOG_DEBUG, "%s ftpget result is: %d,%s\n", processName, result, curl_easy_strerror(result));
|
||
if (result == CURLE_OK) {
|
||
//成功,处理文件
|
||
vLog(LOG_DEBUG, "%s get %s to local memory, with name: %s, and password: %s okay, and file length is: %d.\n", processName, remote, user, password, chunk.size);
|
||
ftpget_retry_count = 0;
|
||
if (chunk.size <= (int)(sizeof(struRYDeviceData) << 5)) {
|
||
vLog(LOG_DEBUG, "%s PLC文件生成未完成!\n", processName);
|
||
continue;
|
||
}
|
||
|
||
struRYDeviceData *data = (struRYDeviceData *)chunk.response;
|
||
|
||
int uid = mbt->GetCurUnitID();
|
||
for (int i = 0; i < 250; i++, data++) { //每个文件有250个数据块
|
||
QLONG unix_time = filetime_to_unix(data->localtime);
|
||
DWORD localtime = ((unix_time / 1000) - 28800L);
|
||
|
||
DWORD millisec = unix_time % 1000;
|
||
unix_time = localtime; unix_time *= 1000;
|
||
unix_time += millisec;
|
||
#if 0
|
||
unionCP56Time st;
|
||
st = Time_ttounionCP56Time(localtime);
|
||
vLog(LOG_DEBUG, "data<%d> time is: %04d/%02d/%02d %02d:%02d:%02d.%03d\n", \
|
||
i, \
|
||
st.year + 2000, st.month, st.dayofmonth, \
|
||
st.hour, st.minute, st.millisecond/1000, st.millisecond%1000);
|
||
#endif
|
||
//如何将结构化数据传入,且快速获取
|
||
Json::Value highspeedvalues;
|
||
for (datatypemap::iterator it = highspeedmap.begin(); it != highspeedmap.end(); it++) {
|
||
//获取数据
|
||
LONG dvalue;
|
||
int order = it->first;
|
||
int point = it->second;
|
||
if (GetYCValue(point, fields, (const char *)data, dvalue)) {
|
||
if (GetUnitYCIsFloat(uid, order)) {
|
||
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue);
|
||
} else {
|
||
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue;
|
||
}
|
||
} else {
|
||
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f;
|
||
}
|
||
}
|
||
#ifndef USE_NOPOLL_WEBSOCKET
|
||
publishhistoryHighSpeedData(uid, unix_time, highspeedvalues);
|
||
#else
|
||
publishhistoryHighSpeedData(g_conn, uid, unix_time, highspeedvalues);
|
||
#endif
|
||
|
||
if (i % 25 == 0) { //40ms一个值,每25次位1s
|
||
Json::Value lowspeedvalues;
|
||
for (datatypemap::iterator it = lowspeedmap.begin(); it != lowspeedmap.end(); it++) {
|
||
//获取数据
|
||
LONG dvalue;
|
||
int order = it->first;
|
||
int point = it->second;
|
||
if (GetYCValue(point, fields, (const char *)data, dvalue)) {
|
||
//fprintf(stderr, "get<%d> value is: %d.\n", point, dvalue);
|
||
if (GetUnitYCIsFloat(uid, order)) {
|
||
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue);
|
||
} else {
|
||
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue;
|
||
}
|
||
} else {
|
||
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f;
|
||
}
|
||
}
|
||
for (datatypeposmap::iterator it = yxdatamap.begin(); it != yxdatamap.end(); it++) {
|
||
BOOLEAN bvalue;
|
||
int order = it->first;
|
||
int point = it->second.point;
|
||
int pos = it->second.pos;
|
||
//vLog(LOG_DEBUG, "start to get point is: %d, pos is: %d\n", point, pos);
|
||
if (GetYXValue(point, fields, (const char *)data, pos, bvalue)) {
|
||
lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = (int)bvalue;
|
||
} else {
|
||
lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = 0;
|
||
}
|
||
}
|
||
#ifndef USE_NOPOLL_WEBSOCKET
|
||
publishhistoryLowSpeedData(uid, unix_time, lowspeedvalues);
|
||
#else
|
||
publishhistoryLowSpeedData(g_conn, uid, unix_time, lowspeedvalues);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
if (chunk.response) free(chunk.response);
|
||
|
||
if (bReadCurrentFile) { //读取的是当前文件
|
||
mbt->m_lastFileNo = mbt->m_currentFileNo;
|
||
mbt->m_currentFileNo++;
|
||
if ((mbt->m_currentFileNo - mbt->m_currentDirStartFileNo) % 1000 == 0) {
|
||
//一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0;
|
||
mbt->m_currentDirNo++;
|
||
mbt->m_currentDirStartFileNo = mbt->m_currentFileNo;
|
||
}
|
||
} else { //读取的是未读历史文件
|
||
mbt->m_lastReadFileNo++;
|
||
if ((mbt->m_lastReadFileNo - mbt->m_lastReadDirStartFileNo) % 1000 == 0) {
|
||
//一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0;
|
||
mbt->m_lastReadDirNo++;
|
||
}
|
||
if (mbt->m_curStartDirNo <= mbt->m_lastReadDirNo && mbt->m_curStartFileNo <= mbt->m_lastReadFileNo) {
|
||
vLog(LOG_DEBUG, "%s a已读取完成所有未读的文件。\n", processName);
|
||
mbt->m_bHaveUnReadFile = FALSE;
|
||
}
|
||
}
|
||
bReadCurrentFile = TRUE;
|
||
} else if (result == CURLE_REMOTE_FILE_NOT_FOUND) {
|
||
//文件不存在,尝试60次(1分钟,正常情况下PLC10s生成一个文件)
|
||
//vLog(LOG_DEBUG, "文件不存在, ftpget_retry_count is: %d\n", ftpget_retry_count);
|
||
ftpget_retry_count++;
|
||
if (ftpget_retry_count >= 60) {
|
||
//重新通过modbus程序获取文件夹和最新文件信息
|
||
mbt->m_iv = 0;
|
||
mbt->m_currentDirNo = -1;
|
||
mbt->m_currentFileNo = -1;
|
||
}
|
||
//此处空闲读取未读的文件
|
||
if (mbt->m_bHaveUnReadFile) {
|
||
bReadCurrentFile = FALSE;
|
||
}
|
||
} else if (result == CURLE_REMOTE_ACCESS_DENIED) {
|
||
vLog(LOG_DEBUG, "%s b已读取完成所有未读的文件。\n", processName);
|
||
mbt->m_bHaveUnReadFile = FALSE;
|
||
bReadCurrentFile = TRUE;
|
||
}
|
||
}
|
||
|
||
pthread_exit(0);
|
||
|
||
return ((void*)0);
|
||
}
|
||
|
||
|
||
CHostADSBFProcess::CHostADSBFProcess()
|
||
{
|
||
m_adsDatas[0].inuse = FALSE;
|
||
m_adsDatas[1].inuse = FALSE;
|
||
m_adsDatas[2].inuse = FALSE;
|
||
m_adsDatas[3].inuse = FALSE;
|
||
m_adsDatas[0].adsDataMemAddr = 65535;
|
||
m_adsDatas[1].adsDataMemAddr = 65535;
|
||
m_adsDatas[2].adsDataMemAddr = 65535;
|
||
m_adsDatas[3].adsDataMemAddr = 65535;
|
||
|
||
m_localIp = "192.168.0.1"; //本机IP地址
|
||
m_localNetId = "192.168.0.1.1.1"; //本机IP地址
|
||
m_remoteIp = "192.168.0.2"; //PLC设备ip地址
|
||
m_remoteNetId = "192.168.0.2.1.1";
|
||
|
||
//websocket接口
|
||
m_pid = 0;
|
||
//目录无效
|
||
m_iv = 1;
|
||
m_currentDirNo = -1; //当前目录编号
|
||
m_currentFileNo = -1; //当前文件编号
|
||
m_lastDirNo = -1; //上一目录编号
|
||
m_lastFileNo = -1; //上一文件编号
|
||
m_bFtpRun = FALSE;
|
||
}
|
||
|
||
CHostADSBFProcess::~CHostADSBFProcess()
|
||
{
|
||
if (m_bHaveFTP)
|
||
{
|
||
m_bFtpRun = FALSE;
|
||
vLog(LOG_DEBUG, "保存本协议读取到的那个目录和文件\n");
|
||
char fileName[260];
|
||
snprintf(fileName, sizeof(fileName), "hostads_%d.mem", GetCurID());
|
||
FILE *pf = fopen(fileName, "w+");
|
||
if (pf)
|
||
{
|
||
fwrite(&m_currentDirNo, sizeof(LONG), 1, pf);
|
||
fwrite(&m_currentFileNo, sizeof(LONG), 1, pf);
|
||
fwrite(&m_currentDirStartFileNo, sizeof(LONG), 1, pf);
|
||
fclose(pf);
|
||
}
|
||
}
|
||
if (m_threadRun) {
|
||
m_threadRun = FALSE;
|
||
m_startup.join();
|
||
}
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::calc(void)
|
||
{
|
||
int n, uid;
|
||
|
||
uid = GetCurUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
|
||
|
||
m_adsDatas[0].inuse = FALSE;
|
||
m_adsDatas[1].inuse = FALSE;
|
||
m_adsDatas[2].inuse = FALSE;
|
||
m_adsDatas[3].inuse = FALSE;
|
||
m_adsDatas[0].adsDataMemAddr = 65535;
|
||
m_adsDatas[1].adsDataMemAddr = 65535;
|
||
m_adsDatas[2].adsDataMemAddr = 65535;
|
||
m_adsDatas[3].adsDataMemAddr = 65535;
|
||
//需要给单元添加一个是否有ftp数据的标识
|
||
if (m_bHaveFTP) config.units[uid].state |= 0x20; //存在ftp标识
|
||
|
||
int yccount, ymcount, yxcount;
|
||
yccount = GetUnitYCCount(uid);
|
||
ymcount = GetUnitYMCount(uid);
|
||
yxcount = GetUnitYXCount(uid);
|
||
|
||
//vLog(LOG_DEBUG, "unit %d, yc count is: %d, and yx count is: %d\n", uid, yccount, yxcount);
|
||
|
||
BYTE params[MAX_UNIT_POINT_PARAM_SIZE];
|
||
BYTE* pData = params;
|
||
WORD registerAddr = 0;
|
||
BYTE value_type = 0;
|
||
|
||
for (n = 0; n < yccount; n++)
|
||
{
|
||
pData = GetUnitYCParamByPoint(uid, n);
|
||
if (pData[4] == 1) continue;
|
||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||
{
|
||
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
|
||
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YC));
|
||
} else {
|
||
//vLog(LOG_WARN, "遥测测点配置了相同的寄存器地址\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
|
||
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YC));
|
||
} else {
|
||
//vLog(LOG_WARN, "遥测测点配置了相同的寄存器地址\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
for (n = 0; n < ymcount; n++)
|
||
{
|
||
pData = GetUnitYMParamByPoint(uid, n);
|
||
if (pData[4] == 1) continue;
|
||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||
{
|
||
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
|
||
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YM));
|
||
} else {
|
||
//vLog(LOG_WARN, "遥脉测点配置了相同的寄存器地址\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
|
||
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YM));
|
||
} else {
|
||
//vLog(LOG_WARN, "遥脉测点配置了相同的寄存器地址\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
for (n = 0; n < yxcount; n++)
|
||
{
|
||
pData = GetUnitYXParamByPoint(uid, n);
|
||
if (pData[4] == 1) continue;
|
||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||
value_type = pData[2];
|
||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||
{
|
||
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
|
||
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YX_BYTE + value_type));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
|
||
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
|
||
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
|
||
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YX_BYTE + value_type));
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CHostADSBFProcess::tryStartup()
|
||
{
|
||
m_turbine = NULL;
|
||
pthread_setname_np(pthread_self(), m_pidName.c_str());
|
||
while (m_threadRun) {
|
||
if (m_turbine == NULL) {
|
||
SetLocalAmsNetId(AmsNetId(m_localNetId));
|
||
m_turbine = new AdsDevice{m_remoteIp, AmsNetId(m_remoteNetId), m_remotePort};
|
||
const auto state = m_turbine->GetState();
|
||
vLog(LOG_DEBUG, "%s ADS state: %d devState: %d\n", m_pidName.c_str(), (uint16_t)state.ads, (uint16_t)state.device);
|
||
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES || (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
|
||
{
|
||
vLog(LOG_DEBUG, "read device state error.\n");
|
||
long ret = AddRemoteRoute(m_remoteIp, m_localNetId, m_localIp, std::string("isoftstone"), std::string("admin"), std::string("admin"));
|
||
vLog(LOG_DEBUG, "bbb %s add route return value is: %d\n", m_pidName.c_str(), ret);
|
||
delete m_turbine;
|
||
m_turbine = NULL;
|
||
}
|
||
} else {
|
||
if (m_turbine->IsConnected()) continue;
|
||
delete m_turbine;
|
||
m_turbine = NULL;
|
||
}
|
||
sleep(5);
|
||
}
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::OnPreCreate(int id)
|
||
{
|
||
if (!CProcess::OnPreCreate(id)) return FALSE;
|
||
|
||
if (!GetOption(&m_nOptions, sizeof(m_nOptions)))
|
||
{
|
||
vLog(LOG_DEBUG, "润阳ADS读取配置错误。");
|
||
return FALSE;
|
||
}
|
||
|
||
char ipaddress[32];
|
||
|
||
m_pidName = std::string(GetCurProcessName());
|
||
//本机IP和netid
|
||
memset(ipaddress, '\0', sizeof(ipaddress));
|
||
inet_ntop(AF_INET, &m_nOptions.net.bind_addr, ipaddress, 16);
|
||
m_localIp = std::string(ipaddress);
|
||
m_localNetId = m_localIp + std::string(".1.1");
|
||
//目标IP和netid
|
||
memset(ipaddress, '\0', sizeof(ipaddress));
|
||
inet_ntop(AF_INET, &m_nOptions.net.target_addr, ipaddress, 16);
|
||
m_remoteIp = std::string(ipaddress);
|
||
m_remoteNetId = m_remoteIp + std::string(".1.1");
|
||
//目标端口
|
||
m_remotePort = m_nOptions.net.target_port;
|
||
|
||
m_bHaveFTP = m_nOptions.bHaveFTP;
|
||
calc();
|
||
|
||
//vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str());
|
||
|
||
m_turbine = NULL;
|
||
SetLocalAmsNetId(AmsNetId(m_localNetId));
|
||
#if 0
|
||
m_threadRun = TRUE;
|
||
m_startup = std::thread(&CHostADSBFProcess::tryStartup, this);
|
||
#endif
|
||
if (m_bHaveFTP)
|
||
{
|
||
snprintf(m_user, sizeof(m_user), "%s", m_nOptions.ftp.user);
|
||
snprintf(m_password, sizeof(m_password), "%s", m_nOptions.ftp.password);
|
||
snprintf(m_remotePath, sizeof(m_remotePath), "%s", m_nOptions.ftp.remotePath);
|
||
snprintf(m_localPath, sizeof(m_localPath), "%s", m_nOptions.ftp.localPath);
|
||
|
||
//读取文件
|
||
m_lastReadDirNo = 1;
|
||
m_lastReadFileNo = 1;
|
||
m_lastReadDirStartFileNo = 1;
|
||
m_bHaveUnReadFile = TRUE;
|
||
|
||
char fileName[260];
|
||
snprintf(fileName, sizeof(fileName), "hostads_%d.mem", GetCurID());
|
||
FILE *pf = fopen(fileName, "rb");
|
||
if (pf)
|
||
{
|
||
fread(&m_lastReadDirNo, sizeof(LONG), 1, pf);
|
||
fread(&m_lastReadFileNo, sizeof(LONG), 1, pf);
|
||
fread(&m_lastReadDirStartFileNo, sizeof(LONG), 1, pf);
|
||
fclose(pf);
|
||
}
|
||
|
||
|
||
//启动后,创建ftp线程
|
||
if (m_pid <= 0) {
|
||
m_bFtpRun = TRUE;
|
||
vLog(LOG_DEBUG, "ads create a ftp thread.\n");
|
||
|
||
pthread_attr_t attr;
|
||
pthread_attr_init(&attr);
|
||
pthread_attr_setstacksize(&attr, MEMERY_1M);
|
||
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||
|
||
if (pthread_create(&m_pid, &attr, ryftp_process, this) < 0) {
|
||
vLog(LOG_ERROR, "ads create ryftp_process error(%d,%s).\n", errno, strerror(errno));
|
||
return TRUE;
|
||
}
|
||
char name[17];
|
||
snprintf(name, 16, "%s_ftp", m_pidName.c_str());
|
||
pthread_setname_np(m_pid, name);
|
||
|
||
pthread_attr_destroy(&attr);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::Run(void)
|
||
{
|
||
if (!CProcess::Run()) return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::OnTimer(void)
|
||
{
|
||
if (!CProcess::OnTimer()) return FALSE;
|
||
|
||
BOOLEAN sec_changed = FALSE;
|
||
if (last_sec != system32.timers)
|
||
{
|
||
last_sec = system32.timers;
|
||
sec_changed = TRUE;
|
||
}
|
||
if (sec_changed)
|
||
{
|
||
if (m_turbine == NULL) {
|
||
m_turbine = new AdsDevice{m_remoteIp, AmsNetId(m_remoteNetId), m_remotePort};
|
||
const auto state = m_turbine->GetState();
|
||
//vLog(LOG_DEBUG, "%s ADS state: %d devState: %d\n", m_pidName.c_str(), (uint16_t)state.ads, (uint16_t)state.device);
|
||
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES || (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
|
||
{
|
||
vLog(LOG_DEBUG, "read device state error.\n");
|
||
long ret = AddRemoteRoute(m_remoteIp, m_localNetId, m_localIp, std::string("isoftstone"), std::string("admin"), std::string("admin"));
|
||
vLog(LOG_DEBUG, "bbb %s add route return value is: %d\n", m_pidName.c_str(), ret);
|
||
delete m_turbine;
|
||
m_turbine = NULL;
|
||
}
|
||
return TRUE;
|
||
}
|
||
if (!m_turbine->IsConnected()) return TRUE;
|
||
//try {
|
||
if (m_bHaveFTP)
|
||
{ //启动时读取一次,后面自己维护序号
|
||
if ((m_currentDirNo == -1) && (m_currentFileNo == -1))
|
||
{ //当前文件和目录都为-1,程序第一次启动。需要获取ftp目录及文件ID
|
||
readFileID();
|
||
}
|
||
}
|
||
readRealData();
|
||
// } catch (const AdsException& ex) {
|
||
// vLog(LOG_ERROR, "%s AdsException message: %s, remote is: %s:%d\n", m_pidName.c_str(), ex.what(), m_remoteIp.c_str(), m_remotePort);
|
||
// } catch (const std::runtime_error& ex) {
|
||
// vLog(LOG_ERROR, "%s %s\n", m_pidName.c_str(), ex.what());
|
||
// }
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::readDeviceState(const AdsDevice& route)
|
||
{
|
||
const auto state = route.GetState();
|
||
vLog(LOG_DEBUG, "ADS state: %d devState: %d\n", (uint16_t)state.ads, (uint16_t)state.device);
|
||
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES && (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::readFileID()
|
||
{
|
||
int uid = GetCurUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
|
||
|
||
vLog(LOG_DEBUG, "%s here read file info\n", m_pidName.c_str());
|
||
AdsVariable <WORD> wPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (WORD)wPathInfoInvalid);
|
||
AdsVariable <DWORD> wCurrentFolderNo {*m_turbine, ".gwCurrentFolderNo"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wCurrentFolderNo);
|
||
AdsVariable <DWORD> wCurrentFileNo {*m_turbine, ".gwCurrentFileNo"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wCurrentFileNo);
|
||
AdsVariable <DWORD> wFirstFileNoInFolder {*m_turbine, ".gwFirstFileNoInFolder"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoInFolder);
|
||
AdsVariable <DWORD> wFileCountInFolder {*m_turbine, ".gwFileCountInFolder"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFileCountInFolder);
|
||
AdsVariable <DWORD> wFirstFolderNoRecoverable {*m_turbine, ".gwFirstFolderNoRecoverable"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFolderNoRecoverable);
|
||
AdsVariable <DWORD> wFirstFileNoRecoverable {*m_turbine, ".gwFirstFileNoRecoverable"};
|
||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoRecoverable);
|
||
|
||
m_iv = (WORD)wPathInfoInvalid;
|
||
if (m_iv) {
|
||
vLog(LOG_DEBUG, "路径信息无效\n");
|
||
return FALSE;
|
||
}
|
||
//当前文件夹路径名
|
||
m_currentDirNo = (DWORD)wCurrentFolderNo;
|
||
//当前文件夹下最后新文件
|
||
m_currentFileNo = (DWORD)wCurrentFileNo;
|
||
//当前目录文件开始编号
|
||
m_currentDirStartFileNo = (DWORD)wFirstFileNoInFolder;
|
||
|
||
|
||
m_curStartDirNo = m_currentDirNo; //当前开始目录
|
||
m_curStartFileNo = m_currentFileNo; //当前开始文件
|
||
//判断是否有要读取的文件
|
||
if (m_curStartDirNo <= m_lastReadDirNo && m_curStartFileNo <= m_lastReadFileNo)
|
||
{
|
||
vLog(LOG_DEBUG, "%s 不存在未读的文件。\n", m_pidName.c_str());
|
||
m_bHaveUnReadFile = FALSE;
|
||
}
|
||
else
|
||
{
|
||
m_bHaveUnReadFile = TRUE;
|
||
int dir_count = m_curStartDirNo - m_lastReadDirNo + 1;
|
||
int file_count = m_curStartFileNo - m_lastReadFileNo;
|
||
vLog(LOG_DEBUG, "%s 总共有%d个目录的%d个文件未读取。\n", m_pidName.c_str(), dir_count, file_count);
|
||
}
|
||
|
||
vLog(LOG_DEBUG, "%s 最新文件夹编号: %ld, 最新文件名编号: %ld: 最新文件夹中第一个文件的编号: %ld\n", m_pidName.c_str(), m_currentDirNo, m_currentFileNo, m_currentDirStartFileNo);
|
||
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostADSBFProcess::readRealData()
|
||
{
|
||
int uid = GetCurUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
|
||
|
||
for (int k = 0; k < 4; k++)
|
||
{
|
||
if (!m_adsDatas[k].inuse) continue;
|
||
WORD m_adsOverviewDataMemAddr = m_adsDatas[k].adsDataMemAddr;
|
||
register2typemap m_register2type_map = m_adsDatas[k].adsDataBlocks;
|
||
|
||
BYTE buffer[1024];
|
||
BYTE *pData = buffer;
|
||
|
||
BYTE params[MAX_UNIT_POINT_PARAM_SIZE];
|
||
BYTE* pParam = params;
|
||
|
||
AdsVariable<std::array<BYTE, MAX_BLOCKF_SIZE>> turbineData {*m_turbine, ADSIGRP_IOIMAGE_RWOB, m_adsOverviewDataMemAddr};
|
||
pData = ((std::array<BYTE, MAX_BLOCKF_SIZE>)turbineData).data();
|
||
|
||
WORD registerAddr = m_adsOverviewDataMemAddr;
|
||
|
||
float f_val;
|
||
DWORD dw[2]; //双精度转换中间变量
|
||
double d_val;
|
||
DWORD bin_value;
|
||
DWORD nValue = 0;
|
||
int point;
|
||
|
||
for (int i = 0; i < MAX_BLOCKF_SIZE;)
|
||
{
|
||
//vLog(LOG_DEBUG, "registerAddr is: %d\n", registerAddr);
|
||
if (m_register2type_map.find(registerAddr) != m_register2type_map.end())
|
||
{
|
||
int type = m_register2type_map[registerAddr];
|
||
if (type == REGISTER_DATA_TYPE_YC)
|
||
{ //遥测
|
||
point = GetUnitYCPointByParam(uid, (BYTE *)®isterAddr, 2);
|
||
if (point >= 0)
|
||
{
|
||
pParam = GetUnitYCParamByPoint(uid, point);
|
||
BYTE value_type = pParam[2]; //数据类型
|
||
BYTE sign_mark = pParam[3];
|
||
|
||
//vLog(LOG_DEBUG, "value type is: %d, ", value_type);
|
||
//32位测量值
|
||
if (0 == value_type)
|
||
{ //浮点数,高位在第一个寄存器
|
||
nValue = (DWORD)(pData[1] << 24 | pData[0] << 16 | pData[3] << 8 | pData[2]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYC(uid, point, f_val);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (1 == value_type)
|
||
{
|
||
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYC(uid, point, f_val);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
//16位归一化值
|
||
else if (2 == value_type)
|
||
{
|
||
if (sign_mark == 0) nValue = (DWORD)(WORD)((pData[1] << 8) | pData[0]);
|
||
else nValue = (DWORD)(short)((pData[1] << 8) | pData[0]);
|
||
SetUnitYC(uid, point, (LONG)nValue);
|
||
//vLog(LOG_DEBUG, "value is: %d \n", nValue);
|
||
registerAddr += 2; i += 2; pData += 2;
|
||
}
|
||
else if (3 == value_type)
|
||
{ //归一化值,高位在第一个寄存器
|
||
nValue = (DWORD)(pData[1] << 24 | pData[0] << 16 | pData[3] << 8 | pData[2]);
|
||
SetUnitYC(uid, point, (LONG)nValue);
|
||
registerAddr += 2; i += 2; pData += 2;
|
||
}
|
||
else if (4 == value_type)
|
||
{ //归一化值,高位在第二个寄存器
|
||
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
|
||
SetUnitYC(uid, point, (LONG)nValue);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
|
||
}
|
||
else if (5 == value_type)
|
||
{ //小端系统浮点值
|
||
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYC(uid, point, f_val);
|
||
//vLog(LOG_DEBUG, "value is: %f\n", f_val);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (6 == value_type)
|
||
{ //32位bcd数据高位在第一个寄存器
|
||
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
|
||
bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD));
|
||
SetUnitYC(uid, point, (LONG)bin_value);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (7 == value_type)
|
||
{ //32位bcd数据高位在第二个寄存器
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD));
|
||
SetUnitYC(uid, point, (LONG)bin_value);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (8 == value_type)
|
||
{ //16位BCD
|
||
if (sign_mark == 0) nValue = (DWORD)(WORD)((pData[1] << 8) | pData[0]);
|
||
else nValue = (DWORD)(short)((pData[1] << 8) | pData[0]);
|
||
nValue = bcd_to_int((const BYTE*)&nValue, sizeof(WORD));
|
||
SetUnitYC(uid, point, (LONG)nValue);
|
||
registerAddr += 2; i += 2; pData += 2;
|
||
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
|
||
}
|
||
else if (9 == value_type)
|
||
{ //
|
||
if (sign_mark == 0) nValue = (DWORD)(BYTE)(pData[0]);
|
||
else nValue = (DWORD)(short)(pData[0]);
|
||
SetUnitYC(uid, point, (LONG)nValue);
|
||
registerAddr++; i++; pData++;
|
||
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
|
||
}
|
||
else
|
||
{
|
||
registerAddr++; i++; pData++;
|
||
}
|
||
}
|
||
}
|
||
else if (type == REGISTER_DATA_TYPE_YM)
|
||
{ //遥脉
|
||
point = GetUnitYMPointByParam(uid, (BYTE *)®isterAddr, 2);
|
||
if (point >= 0)
|
||
{
|
||
pParam = GetUnitYMParamByPoint(uid, point);
|
||
BYTE value_type = pParam[2]; //数据类型
|
||
if (0 == value_type)
|
||
{ //16位无符号整型
|
||
nValue = (pData[1] << 8) | pData[0];
|
||
SetUnitYM(uid, point, nValue);
|
||
registerAddr += 2; i += 2; pData += 2;
|
||
}
|
||
else if (1 == value_type)
|
||
{ //32位无符号整型高位在第一个寄存器
|
||
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
|
||
SetUnitYM(uid, point, nValue);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (2 == value_type)
|
||
{ //32位整型高位在第一个寄存器
|
||
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
|
||
SetUnitYM(uid, point, nValue);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (3 == value_type)
|
||
{ //32位无符号整型高位在第二个寄存器
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
SetUnitYM(uid, point, nValue);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (4 == value_type)
|
||
{ //32位整型高位在第二个寄存器
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
SetUnitYM(uid, point, nValue);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (5 == value_type)
|
||
{ //32位浮点数高位在第一个寄存器
|
||
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYM(uid, point, (DWORD)f_val);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (6 == value_type)
|
||
{ //32位浮点数高位在第二个寄存器
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYM(uid, point, (DWORD)f_val);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else if (7 == value_type)
|
||
{ //64位浮点数高位在第一个寄存器
|
||
dw[1] = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
dw[0] = (DWORD)((pData[7] << 24) | (pData[6] << 16) | (pData[5] << 8) | pData[4]);
|
||
memcpy(&d_val, dw, 8);
|
||
SetUnitYM(uid, point, (DWORD)(d_val));
|
||
registerAddr += 8; i += 8; pData += 8;
|
||
}
|
||
else if (8 == value_type)
|
||
{
|
||
dw[0] = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
dw[1] = (DWORD)((pData[7] << 24) | (pData[6] << 16) | (pData[5] << 8) | pData[4]);
|
||
memcpy(&d_val, dw, 8);
|
||
SetUnitYM(uid, point, (DWORD)(d_val));
|
||
registerAddr += 8; i += 8; pData += 8;
|
||
}
|
||
else if (9 == value_type)
|
||
{
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
memcpy(&f_val, &nValue, 4);
|
||
SetUnitYM(uid, point, (DWORD)(f_val * 10));
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
}
|
||
else
|
||
{
|
||
registerAddr++; i++; pData++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{ //遥信
|
||
int data_bits = 8;
|
||
BYTE params[4];
|
||
params[0] = (BYTE)(registerAddr & 0xff);
|
||
params[1] = (BYTE)((registerAddr >> 8) & 0xff);
|
||
params[2] = type - REGISTER_DATA_TYPE_YX_BYTE;
|
||
if (type == REGISTER_DATA_TYPE_YX_BYTE)
|
||
{
|
||
nValue = (DWORD)pData[0];
|
||
registerAddr++; i++; pData++;
|
||
data_bits = 8;
|
||
}
|
||
else if (type == REGISTER_DATA_TYPE_YX_WORD)
|
||
{
|
||
nValue = (DWORD)((pData[1] << 8) | pData[0]);
|
||
registerAddr += 2; i += 2; pData += 2;
|
||
data_bits = 16;
|
||
}
|
||
else if (type == REGISTER_DATA_TYPE_YX_DWORD)
|
||
{
|
||
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
|
||
registerAddr += 4; i += 4; pData += 4;
|
||
data_bits = 32;
|
||
}
|
||
else
|
||
{
|
||
registerAddr++; i++; pData++;
|
||
}
|
||
DWORD nTemp = 0x00000001;
|
||
for (int j = 0; j < data_bits; j++)
|
||
{
|
||
params[3] = j;
|
||
point = GetUnitYXPointByParam(uid, (BYTE *)params, 4);
|
||
if (point >= 0)
|
||
{
|
||
BOOLEAN yxVal = SPI_OFF;
|
||
if ((nValue) & nTemp)
|
||
{
|
||
yxVal = SPI_ON;
|
||
}
|
||
SetUnitYX(uid, point, yxVal);
|
||
}
|
||
nTemp <<= 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
registerAddr++; i++; pData++;
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|