From 41c692ee8b40e3999cdab55724c8da5d80f4fde4 Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Fri, 15 Nov 2024 16:12:14 +0800 Subject: [PATCH] add minio --- das-dn/CMakeLists.txt | 11 +- das-dn/CMakePresets.json | 13 + das-dn/cmg/changemaster.cpp | 6 + das-dn/cmg/main.cpp | 2177 +--------------------- das-dn/cmg/ry.cpp | 481 ++++- das-dn/cmg/ry.h | 29 +- das-dn/comm/public.cpp | 59 + das-dn/hostmodbustcp/host_modbus_tcp.cpp | 188 +- das-dn/hostmodbustcp/host_modbus_tcp.h | 25 +- das-dn/inc/public.h | 38 +- das-dn/minio/ftp2minio.cpp | 375 ++++ das-dn/minio/ftp2minio.h | 65 + 12 files changed, 1135 insertions(+), 2332 deletions(-) create mode 100644 das-dn/CMakePresets.json create mode 100644 das-dn/minio/ftp2minio.cpp create mode 100644 das-dn/minio/ftp2minio.h diff --git a/das-dn/CMakeLists.txt b/das-dn/CMakeLists.txt index 177b1870..4bd84e89 100644 --- a/das-dn/CMakeLists.txt +++ b/das-dn/CMakeLists.txt @@ -1,8 +1,11 @@ -cmake_minimum_required (VERSION 3.5.1) +cmake_minimum_required (VERSION 3.20) project (application C CXX) set (VERSION 1.0.1) +# 指定C++标准 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -option (USE_MQTT "use mqtt protocol" ON) +option (USE_MQTT "use mqtt protocol" OFF) option (USE_WEBSOCKET "use websocket" ON) option (USE_SQLITE3 "use sqlite3" ON) @@ -48,6 +51,9 @@ if (HAVE_FTP_PROCESS) set (APP_LIBS ${APP_LIBS} curl) endif () +find_package(miniocpp REQUIRED) +target_link_libraries(application PRIVATE miniocpp::miniocpp) + include_directories ( inc inc/json @@ -77,6 +83,7 @@ set (APP_SRCS rtustatusproc/rtustatus.cpp subiec104/sub_iec104.cpp zjd3100proc/zjd3100pro.cpp + minio/ftp2minio.cpp ) set (APP_SRCS ${APP_SRCS} diff --git a/das-dn/CMakePresets.json b/das-dn/CMakePresets.json new file mode 100644 index 00000000..a24419ba --- /dev/null +++ b/das-dn/CMakePresets.json @@ -0,0 +1,13 @@ +{ + "version": 3, + + "configurePresets": [ + { + "name": "debug", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + } + } + ] +} diff --git a/das-dn/cmg/changemaster.cpp b/das-dn/cmg/changemaster.cpp index 6f67b7d5..004fc834 100644 --- a/das-dn/cmg/changemaster.cpp +++ b/das-dn/cmg/changemaster.cpp @@ -6,6 +6,7 @@ #include "../hostmodbustcp/host_modbus_tcp.h" #include "../rtustatusproc/rtustatus.h" #include "../zjd3100proc/zjd3100pro.h" +#include "../minio/ftp2minio.h" //#include "../bfftpfile2issmqtt/bfftpfile2issmqtt.h" #ifdef USE_WEBSOCKET #endif @@ -354,6 +355,11 @@ void CChangeMaster::StartUp(void) vLog(LOG_INFO, "协议<%d>创建为: iec104从协议.\n", i); procs[i] = new CSubIEC104Process(); } + else if (PROTOCOL_FTP2MINIO == config.processes[i].proto) + { + vLog(LOG_INFO, "协议<%d>创建为: FTP读取转MINIO存储协议.\n", i); + procs[i] = new CFtp2MinioProcess(); + } else if (PROTOCOL_LOCAL_DEBUG == config.processes[i].proto) {//Local debug vLog(LOG_INFO, "协议<%d>创建为: 本地调试协议.\n", i); diff --git a/das-dn/cmg/main.cpp b/das-dn/cmg/main.cpp index b58aab49..4b9bb7ca 100644 --- a/das-dn/cmg/main.cpp +++ b/das-dn/cmg/main.cpp @@ -13,2029 +13,6 @@ #include "ry.h" -#ifdef MAIN_FILE -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "soe.h" -#include "yklog.h" -#include "ytlog.h" -#include "public.h" - -#define MAX_MSG_COUNT 4096 - -bool g_dataAcquisitionReload = false; - - -std::string g_traceId; - -LONG m_soeload = 0; -LONG m_yxbwload = 0; -LONG m_ycbwload = 0; - -typedef std::unordered_map uid2pidmap; -uid2pidmap uid2pid_map; - -#define CMD_CONTROL_OPERATION 0 -#define CMD_CONTROL_SETTING 1 -typedef struct { - int uid; - int point; - int order; - int type; -} struct_service_item; - -typedef std::unordered_map name2servicemap; -typedef std::unordered_map unitname2servicemap; -unitname2servicemap unitname2service_map; - -typedef struct { - std::string name; - Json::Value value; -} struct_attr; -typedef std::vector attrvector; - -#define WORKER_ID_BITS 5 -#define DATA_CENTER_ID_BITS 5 -#define SEQUENCE_BITS 12 -#define MAX_WORKER_ID ((1 << WORKER_ID_BITS) - 1) -#define MAX_DATA_CENTER_ID ((1 << DATA_CENTER_ID_BITS) - 1) -#define SEQUENCE_MASK ((1 << SEQUENCE_BITS) - 1) - -#define EPOCH 1640995200000 // 2022-01-01 00:00:00 - -typedef struct { - uint64_t worker_id; - uint64_t data_center_id; - uint64_t sequence; - uint64_t last_timestamp; -} Snowflake; - -uint64_t current_time() { - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); -} - -uint64_t snowflake_next_id(Snowflake *sf) { - uint64_t timestamp = current_time(); - if (timestamp < sf->last_timestamp) { - return 0; - } - if (sf->last_timestamp == timestamp) { - sf->sequence = (sf->sequence + 1) & SEQUENCE_MASK; - if (sf->sequence == 0) { - while (current_time() <= sf->last_timestamp); - } - } else { - sf->sequence = 0; // reset sequence - } - sf->last_timestamp = timestamp; - return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) | - (sf->data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) | - (sf->worker_id << SEQUENCE_BITS) | - sf->sequence; -} - -Snowflake g_sf = {1, 1, 0, 0}; - -std::vector split(const std::string &s, char delimiter) -{ - std::vector tokens; - std::istringstream tokenStream(s); - std::string token; - while (std::getline(tokenStream, token, delimiter)) { - tokens.push_back(token); - } - return tokens; -} - -struSystem config_system32; -struConfig config_config; -struDatabase config_database; -struNodeOption config_nodes; -struUnitStatic config_static_units[UNIT_NUM]; - -bool configInitializeMemory(void) -{ - int i, j; - - if (config_database.yxs) delete [] config_database.yxs; - if (config_database.ycs) delete [] config_database.ycs; - if (config_database.yms) delete [] config_database.yms; - if (config_database.yks) delete [] config_database.yks; - if (config_database.yts) delete [] config_database.yts; - - for (i = 0; i < UNIT_NUM; i++) { - if (config_config.units[i].yxs) delete [] config_config.units[i].yxs; - if (config_config.units[i].ycs) delete [] config_config.units[i].ycs; - if (config_config.units[i].yms) delete [] config_config.units[i].yms; - if (config_config.units[i].yks) delete [] config_config.units[i].yks; - if (config_config.units[i].yts) delete [] config_config.units[i].yts; - } - - memset(&config_system32, 0, sizeof(config_system32)); - memset(&config_config, 0, sizeof(config_config)); - memset(&config_database, 0, sizeof(config_database)); - memset(&config_nodes, 0, sizeof(config_nodes)); - memset(config_static_units, 0, sizeof(config_static_units)); - - config_database.yxs = new struYX[DATABASE_YX_NUM]; - if (config_database.yxs == NULL) return FALSE; - memset(config_database.yxs, 0, sizeof(struYX) * DATABASE_YX_NUM); - - config_database.ycs = new struYC[DATABASE_YC_NUM]; - if (config_database.ycs == NULL) return FALSE; - memset(config_database.ycs, 0, sizeof(struYC) * DATABASE_YC_NUM); - - config_database.yms = new struYM[DATABASE_YM_NUM]; - if (config_database.yms == NULL) return FALSE; - memset(config_database.yms, 0, sizeof(struYM) * DATABASE_YM_NUM); - - config_database.yks = new struYK[DATABASE_YK_NUM]; - if (config_database.yks == NULL) return FALSE; - memset(config_database.yks, 0, sizeof(struYK) * DATABASE_YK_NUM); - - config_database.yts = new struYT[DATABASE_YT_NUM]; - if (config_database.yts == NULL) return FALSE; - memset(config_database.yts, 0, sizeof(struYT) * DATABASE_YT_NUM); - - strcpy(config_system32.yk_pass, "12345"); - snprintf(config_system32.version, sizeof(config_system32.version), "%s", "0"); - config_system32.yk_keep = 30; - config_system32.interval_time = 2; - config_system32.log_enabled = FALSE; - config_system32.zjd_log_bind_addr = INADDR_ANY; - config_system32.zjd_log_bind_port = 0; - for (i = 0; i < HARDWARE_PORTS_NUM; i++) { - config_config.hardware.ports[i].baud = 9600; - config_config.hardware.ports[i].data = 8; - config_config.hardware.ports[i].parity = 0; - config_config.hardware.ports[i].stop = 0; - config_config.hardware.ports[i].timeout = 1000; //1s - } - for (i = 0; i < PROCESSES_NUM; i++) { - config_config.processes[i].softdog = 0; - for (j = 0; j < PROCESS_UNIT_NUM; j++) { - config_config.processes[i].units[j] = -1; - } - } - for (i = 0; i < UNIT_NUM; i++) { - config_config.units[i].softdog = 0; - } - - return true; -} - - -bool configWriteSystemCFG(void) -{ - FILE* pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_SYSTEM_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - fwrite(&config_system32, sizeof(config_system32), 1, pf); - fclose(pf); - return true; - } - return false; -} - -bool configWriteNodeCFG(void) -{ - FILE *pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_NODE_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - fwrite(&config_nodes, sizeof(config_nodes), 1, pf); - fclose(pf); - return true; - } - return false; -} - -bool configWriteHardwareCFG(void) -{ - FILE* pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_HARDWARE_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - fwrite(&config_config.hardware, sizeof(config_config.hardware), 1, pf); - fclose(pf); - return true; - } - return false; -} - -bool configWriteProcessCFG(void) -{ - FILE* pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_PROCESS_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - fwrite(&config_config.processes, sizeof(config_config.processes), 1, pf); - fclose(pf); - return true; - } - return false; -} - -bool configWriteUnitCFG(void) -{ - int i; - char filename[512]; - char pathName[512]; - FILE *pf = NULL; - FILE *pfPoint = NULL; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - for (i = 0; i < UNIT_NUM; i++) { - if (fwrite(&config_config.units[i], sizeof(config_config.units[i]), 1, pf) != 1) break; - if (config_config.units[i].yxcount > 0) { - if (config_config.units[i].yxs != NULL) { - snprintf(filename, sizeof(filename), FILE_UNIT_YX_CONFIG, configpath, i); - pfPoint = fopen(filename, "wb+"); - if (pfPoint != NULL) { - fwrite(config_config.units[i].yxs, sizeof(struUnitYX)*config_config.units[i].yxcount, 1, pfPoint); - fclose(pfPoint); - } - } - } - if (config_config.units[i].yccount > 0) { - if (config_config.units[i].ycs != NULL) { - snprintf(filename, sizeof(filename), FILE_UNIT_YC_CONFIG, configpath, i); - pfPoint = fopen(filename, "wb+"); - if (pfPoint != NULL) { - fwrite(config_config.units[i].ycs, sizeof(struUnitYC)*config_config.units[i].yccount, 1, pfPoint); - fclose(pfPoint); - } - } - } - if (config_config.units[i].ymcount > 0) { - if (config_config.units[i].yms != NULL) { - snprintf(filename, sizeof(filename), FILE_UNIT_YM_CONFIG, configpath, i); - pfPoint = fopen(filename, "wb+"); - if (pfPoint != NULL) { - fwrite(config_config.units[i].yms, sizeof(struUnitYM)*config_config.units[i].ymcount, 1, pfPoint); - fclose(pfPoint); - } - } - } - if (config_config.units[i].ykcount > 0) { - if (config_config.units[i].yks != NULL) { - snprintf(filename, sizeof(filename), FILE_UNIT_YK_CONFIG, configpath, i); - pfPoint = fopen(filename, "wb+"); - if (pfPoint != NULL) { - fwrite(config_config.units[i].yks, sizeof(struUnitYK)*config_config.units[i].ykcount, 1, pfPoint); - fclose(pfPoint); - } - } - } - if (config_config.units[i].ytcount > 0) { - if (config_config.units[i].yts != NULL) { - snprintf(filename, sizeof(filename), FILE_UNIT_YT_CONFIG, configpath, i); - pfPoint = fopen(filename, "wb+"); - if (pfPoint != NULL) { - fwrite(config_config.units[i].yts, sizeof(struUnitYT)*config_config.units[i].ytcount, 1, pfPoint); - fclose(pfPoint); - } - } - } - } - fclose(pf); - return true; - } - return false; -} - -bool configWriteStaticUnitCFG(void) -{ - FILE *pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_STATIC); - pf = fopen(pathName, "w+"); - if (pf != NULL) { - fwrite(config_static_units, sizeof(config_static_units), 1, pf); - fclose(pf); - return true; - } - return false; -} - -bool configWriteDatabaseCFG(void) -{ - FILE *pf; - char pathName[512]; - - snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_DATABASE_CONFIG); - pf = fopen(pathName, "wb+"); - if (pf != NULL) { - fwrite(config_database.yxs, sizeof(struYX) * DATABASE_YX_NUM, 1, pf); - fwrite(config_database.ycs, sizeof(struYC) * DATABASE_YC_NUM, 1, pf); - fwrite(config_database.yms, sizeof(struYM) * DATABASE_YM_NUM, 1, pf); - fwrite(config_database.yks, sizeof(struYK) * DATABASE_YK_NUM, 1, pf); - fwrite(config_database.yts, sizeof(struYT) * DATABASE_YT_NUM, 1, pf); - fclose(pf); - return true; - } - return false; -} - -BOOLEAN websocket_msg_join(noPollMsg **msg, int msg_count, BYTE* &buffer, int &buffer_size) -{ - if (msg_count <= 0 || msg_count >= MAX_MSG_COUNT) return FALSE; - if (msg[0] == NULL) return FALSE; - buffer_size = 0; - for (int i = 0; i < msg_count; i++) - { - buffer_size += nopoll_msg_get_payload_size(msg[i]); - } - buffer = new BYTE[buffer_size + 1]; - int len = 0; - for (int i = 0; i < msg_count; i++) - { - memcpy(&buffer[len], nopoll_msg_get_payload(msg[i]), nopoll_msg_get_payload_size(msg[i])); - len += nopoll_msg_get_payload_size(msg[i]); - } - buffer[buffer_size] = 0; - return TRUE; -} - -int websocket_write(noPollConn* conn, const char * buffer, int buffer_len) -{ - int result; - result = nopoll_conn_send_text(conn, (const char *)buffer, buffer_len); - /* ensure we have written all bytes but limit operation to 2 seconds */ - result = nopoll_conn_flush_writes(conn, 2000000, result); - return (result == buffer_len) ? 0 : -1; -} - -bool publish_sensor_data(noPollConn* conn, const std::string traceId, const char* command, const Json::Value payload) -{ - Json::StreamWriterBuilder builder; - builder["indentation"] = ""; - builder["emitUTF8"] = true; - - Json::Value jsonRoot; - jsonRoot["cmd"] = command; - - char str[128]; - snprintf(str, sizeof(str), "%lld", snowflake_next_id(&g_sf)); - - if (traceId == "") { - jsonRoot["cmdId"] = str; - } else { - jsonRoot["cmdId"] = traceId; - } - - Json::Int64 mtime = (Json::Int64)time(NULL); - mtime *= 1000; - jsonRoot["time"] = mtime; - jsonRoot["data"] = payload; - - std::string outputConfig = Json::writeString(builder, jsonRoot); - vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n%s\n", command, outputConfig.length(), outputConfig.c_str()); - int rc = websocket_write(conn, outputConfig.c_str(), outputConfig.length()); - if (rc != 0) { - vLog(LOG_DEBUG, "websocket write is error<%d>,insert into database.\n", rc); - //插入数据库 - return false; - } - - return true; -} - -static int GetUnitYXCount(int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return 0; - return config.units[uid].yxcount; -} - -static int GetUnitYCCount(int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return 0; - return config.units[uid].yccount; -} - -static int GetUnitYMCount(int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return 0; - return config.units[uid].ymcount; -} - -static float GetUnitYCReal(int uid, int order) -{ - int udb; - long value; - float coef; - float base; - struUnit* pUnit; - struUnitYC* pYC; - if (uid < 0 || uid >= UNIT_NUM) return 0; - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return 0; - if (order < 0 || order >= pUnit->yccount) return 0; - pYC = &pUnit->ycs[order]; - udb = pYC->order; - if (udb < 0 || udb >= DATABASE_YC_NUM) { - value = pYC->value; - coef = 1.0f; - base = 0.0f; - } else { - value = database.ycs[udb].value; - coef = pYC->coef; - base = pYC->base; - pYC->value = value; - pYC->update_time = database.ycs[udb].update_time; - pYC->qds = database.ycs[udb].qds; - } - return (float)((float)value * coef + base); -} - -static float GetUnitYCRealFromValue(int uid, int order, long value) -{ - int udb; - float coef; - float base; - struUnit* pUnit; - struUnitYC* pYC; - - if (uid < 0 || uid >= UNIT_NUM) return 0; - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return 0; - if (order < 0 || order >= pUnit->yccount) return 0; - pYC = &pUnit->ycs[order]; - udb = pYC->order; - if (udb < 0 || udb >= DATABASE_YC_NUM) { - coef = 1.0f; - base = 0.0f; - } else { - coef = pYC->coef; - base = pYC->base; - } - return (float)(value * coef + base); -} - -static float GetUnitYMReal(int uid, int order) -{ - int udb; - long value; - float coef; - float base; - struUnit* pUnit; - struUnitYM* pYM; - if (uid < 0 || uid >= UNIT_NUM) return 0; - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return 0; - if (order < 0 || order >= pUnit->ymcount) return 0; - pYM = &pUnit->yms[order]; - udb = pYM->order; - if (udb < 0 || udb >= DATABASE_YM_NUM) { - value = pYM->value; - coef = 1.0f; - base = 0.0f; - } else { - value = (long)database.yms[udb].value; - pYM->update_time = database.yms[udb].update_time; - coef = pYM->coef; - base = pYM->base; - pYM->value = value; - } - return (float)(value * coef + base); -} - -static BYTE GetUnitYX(int uid, int point) -{ - int udb; - BOOLEAN value; - struUnit* pUnit; - struUnitYX* pYX; - - if (uid < 0 || uid >= UNIT_NUM) return 0; - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return 0; - if (point < 0 || point >= pUnit->yxcount) return 0; - pYX = &pUnit->yxs[point]; - udb = pYX->order; - if (udb < 0 || udb >= DATABASE_YX_NUM) { - value = pYX->value; - } else { - value = database.yxs[udb].value; - pYX->value = value; - pYX->update_time = database.yxs[udb].update_time; - } - return value; -} - -int GetUnitYXBW(int& uid, BOOLEAN& value, BYTE& qds, int& type, unionCP56Time& st) -{ - int order; - int point; - - while (yxbw.GetYXBW(m_yxbwload, st, order, value, qds, uid, point, type)) - { - m_yxbwload++; - return point; - } - return -1; -} - -int GetUnitSOE(int& uid, BOOLEAN& value, BYTE& qds, unionCP56Time& st) -{ - int order; - int point; - - while (soe.GetSOE(m_soeload, st, order, value, qds, uid, point)) { - m_soeload++; - return point; - } - - return -1; -} - -int GetUnitYCBW(int& uid, LONG& value, BYTE& qds, int& type, unionCP56Time& st) -{ - int order; - int point; - - while (ycbw.GetYCBW(m_ycbwload, st, order, value, qds, uid, point, type)) { - m_ycbwload++; - return point; - } - return -1; -} - -BOOLEAN GetUnitYK(int uid, int& order, BYTE& value, BYTE& act, BYTE& result) -{ - int i; - int udb; - struUnit* pUnit; - struYK* pYK; - - if (uid < 0 || uid >= UNIT_NUM) return FALSE; - - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return FALSE; - for (i = 0; i < pUnit->ykcount; i++) { - udb = pUnit->yks[i].order; - if (udb < 0 || udb >= DATABASE_YK_NUM) continue; - pYK = &database.yks[udb]; - order = i; - value = pYK->value; - act = (BYTE)pYK->state; - result = (BYTE)pYK->result; - if (pYK->op_unit != uid) continue; - switch (act) { - case YKS_SELED: - if (result == YKR_SUCC) { - pYK->result = YKR_OPER; - yklog.PushYKLog(system32.now, udb, value, YKT_SELRET, YKS_PROC, uid); - return TRUE; - } else if (result == YKR_FAIL) { - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - return TRUE; - } else if (result == YKR_IDLE) { - pYK->state = YKS_IDLE; - pYK->op_unit = -1; - } - break; - case YKS_EXEED: - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - if (result == YKR_SUCC || result == YKR_FAIL) { - return TRUE; - } - break; - case YKS_ABRED: - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - return TRUE; - case YKS_EXEING: - if (result == YKR_OVER) { - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - return TRUE; - } - break; - case YKS_SELREQ: - if (result == YKR_OVER) { - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - return TRUE; - } - break; - case YKS_SELING: - if (result == YKR_OVER) { - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - return TRUE; - } - break; - case YKS_ABRREQ: - case YKS_EXEREQ: - case YKS_IDLE: - break; - default: - pYK->state = YKS_IDLE; - pYK->result = YKR_IDLE; - pYK->op_unit = -1; - break; - } - } - - return FALSE; -} - -void SetUnitYK(int uid, int order, BYTE value, BYTE act, BYTE result) -{ - int udb; - struUnit* pUnit; - struYK* pYK; - - if (uid < 0 || uid >= UNIT_NUM) return; - - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return; - if (order < 0 || order >= pUnit->ykcount) return; - udb = pUnit->yks[order].order; - if (udb < 0 || udb >= DATABASE_YK_NUM) return; - pYK = &database.yks[udb]; - switch (act) { - case YKS_SELREQ: - if (pYK->state == YKS_IDLE /*&& pYK->op_unit == -1*/) { - pYK->state = act; - pYK->result = YKR_IDLE; - pYK->value = value; - pYK->op_time = system32.timers; - pYK->op_unit = uid; - yklog.PushYKLog(system32.now, udb, value, YKT_SELREQ, YKS_PROC, uid); - } - break; - case YKS_ABRREQ: - if (pYK->op_unit != uid) break; - if (pYK->value != value) break; - if (pYK->state != YKS_IDLE && pYK->state != YKS_EXEED) { - pYK->state = act; - pYK->result = YKR_IDLE; - yklog.PushYKLog(system32.now, udb, value, YKT_ABRREQ, YKS_PROC, uid); - } - break; - case YKS_EXEREQ: - if (pYK->op_unit != uid) break; - if (pYK->value != value) break; - if (pYK->state == YKS_SELED && pYK->result == YKR_OPER) { - pYK->state = act; - pYK->result = YKR_IDLE; - yklog.PushYKLog(system32.now, udb, value, YKT_EXEREQ, YKS_PROC, uid); - } - break; - } -} - -BOOLEAN GetUnitYT(int uid, int& order, DWORD& value, BYTE& act, BYTE& result) -{ - int i; - int udb; - struUnit* pUnit; - struYT* pYT; - - if (uid < 0 || uid >= UNIT_NUM) return FALSE; - - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return FALSE; - for (i = 0; i < pUnit->ytcount; i++) { - udb = pUnit->yts[i].order; - if (udb < 0 || udb >= DATABASE_YT_NUM) continue; - pYT = &database.yts[udb]; - order = i; - value = (DWORD)pYT->value; - act = (BYTE)pYT->state; - result = (BYTE)pYT->result; - if (pYT->op_unit != uid) continue; - switch (act) { - case YTS_SELED: - if (result == YTR_SUCC) { - pYT->result = YTR_OPER; - ytlog.PushYTLog(system32.now, udb, value, YTT_SELRET, YTS_PROC, uid); - return TRUE; - } else if (result == YTR_FAIL) { - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - return TRUE; - } else if (result == YTR_IDLE) { - pYT->state = YTS_IDLE; - pYT->op_unit = -1; - } - break; - case YTS_EXEED: - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - if (result == YTR_SUCC || result == YTR_FAIL) { - return TRUE; - } - break; - case YTS_ABRED: - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - return TRUE; - case YTS_EXEING: - if (result == YTR_OVER) { - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - return TRUE; - } - break; - case YTS_SELREQ: - if (result == YTR_OVER) { - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - return TRUE; - } - break; - case YTS_SELING: - if (result == YTR_OVER) { - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - return TRUE; - } - break; - case YTS_ABRREQ: - case YTS_EXEREQ: - case YTS_IDLE: - break; - default: - pYT->state = YTS_IDLE; - pYT->result = YTR_IDLE; - pYT->op_unit = -1; - break; - } - } - - return FALSE; -} - -void SetUnitYT(int uid, int order, DWORD value, BYTE act, BYTE result) -{ - int udb; - struUnit* pUnit; - struYT* pYT; - - if (uid < 0 || uid >= UNIT_NUM) return; - - pUnit = &config.units[uid]; - if ((pUnit->state & 0x01) != TRUE) return; - if (order < 0 || order >= pUnit->ytcount) return; - udb = pUnit->yts[order].order; - if (udb < 0 || udb >= DATABASE_YT_NUM) return; - pYT = &database.yts[udb]; - switch (act) { - case YTS_SELREQ: - if (pYT->state == YTS_IDLE /*&& pYT->op_unit == -1*/) { - pYT->state = act; - pYT->result = YTR_IDLE; - pYT->value = value; - pYT->op_time = system32.timers; - pYT->op_unit = uid; - ytlog.PushYTLog(system32.now, udb, value, YTT_SELREQ, YTS_PROC, uid); - } - break; - case YTS_ABRREQ: - if (pYT->op_unit != uid) break; - if (pYT->value != (long)value) break; - if (pYT->state != YTS_IDLE && pYT->state != YTS_EXEED) { - pYT->state = act; - pYT->result = YTR_IDLE; - ytlog.PushYTLog(system32.now, udb, value, YTT_ABRREQ, YTS_PROC, uid); - } - break; - case YTS_EXEREQ: - if ((pYT->state == YTS_SELED || pYT->state == YTS_IDLE)) { - pYT->state = act; - pYT->result = YTR_IDLE; - pYT->value = value; - pYT->op_time = system32.timers; - pYT->op_unit = uid; - ytlog.PushYTLog(system32.now, udb, value, YTT_EXEREQ, YTS_PROC, uid); - } - break; - } -} - -int MakeYKFrame(noPollConn* conn, int uid) -{ - int order; - BYTE value, action, result; - - //for (int i = 0; i < m_total_units.size(); i++) - { - //uid = m_total_units.at(i); - if (uid < 0 || uid >= UNIT_NUM) return -1; - if (!GetUnitYK(uid, order, value, action, result)) return -1; - - vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is %s result is %s\n", uid, order, (value ? "CLOSE" : "TRIP"), val_to_str(action, yk_state, "STATE=%d"), val_to_str(result, yk_result, "RESULT=%d")); - - //发送确认 - Json::Value jsonRoot; - - jsonRoot["deviceId"] = static_units[uid].deviceId; - jsonRoot["serviceName"] = (const char *)config.units[uid].yks[order].name; - jsonRoot["opValue"] = value; - if (YKS_SELED == action && YKR_FAIL == result) { - action = YKS_ABRED; - } else if (YKS_SELREQ == action && YKR_OVER == result) { - action = YKS_ABRED; - } else if (YKS_SELING == action && YKR_OVER == result) { - action = YKS_ABRED; - } - - if (YKS_SELED == action) { - SetUnitYK(uid, order, value, YKS_EXEREQ, YKR_IDLE); - vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE.\n", uid, order, (value ? "CLOSE" : "TRIP")); - return 1; - } else if (YKS_ABRED == action) { - SetUnitYK(uid, order, value, YKS_ABRREQ, YKR_IDLE); - vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE.\n", uid, order, (value ? "CLOSE" : "TRIP")); - jsonRoot["result"] = false; - } else { - jsonRoot["result"] = true; - } - - publish_sensor_data(conn, g_traceId, "deviceControlResp", jsonRoot); - return 1; - } - return 0; -} - -int MakeYTFrame(noPollConn* conn, int uid) -{ - int order; - BYTE action, result; - DWORD value; - - //for (int i = 0; i < m_total_units.size(); i++) - { - if (uid < 0 || uid >= UNIT_NUM) return -1; - if (!GetUnitYT(uid, order, value, action, result)) return -1; - - vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is %s result is %s\n", uid, order, value, val_to_str(action, yt_state, "STATE=%d"), val_to_str(result, yt_result, "RESULT=%d")); - - //发送确认 - Json::Value jsonRoot; - - jsonRoot["deviceId"] = static_units[uid].deviceId; - jsonRoot["serviceName"] = (const char *)config.units[uid].yts[order].name; - jsonRoot["opValue"] = value; - if (YTS_SELED == action && YTR_FAIL == result) { - action = YTS_ABRED; - } else if (YTS_SELREQ == action && YTR_OVER == result) { - action = YTS_ABRED; - } else if (YTS_SELING == action && YTR_OVER == result) { - action = YTS_ABRED; - } - if (YTS_SELED == action) { - SetUnitYT(uid, order, value, YTS_EXEREQ, YTR_IDLE); - vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE.\n", uid, order, value); - return 1; - } else if (YTS_ABRED == action) { - SetUnitYT(uid, order, value, YTS_ABRREQ, YTR_IDLE); - vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE.\n", uid, order, value); - jsonRoot["result"] = false; - } else { - jsonRoot["result"] = true; - } - - publish_sensor_data(conn, g_traceId, "deviceControlResp", jsonRoot); - return 1; - } - - return 0; -} - -bool OnReceivedDeviceCommand(const Json::Value jsonRoot) -{ - if (jsonRoot["deviceId"].isNull()) return FALSE; - if (jsonRoot["serviceName"].isNull()) return FALSE; - if (jsonRoot["opValue"].isNull()) return FALSE; - - std::string deviceId = jsonRoot["deviceId"].asString(); - std::string serviceName = jsonRoot["serviceName"].asString(); - if (unitname2service_map.find(deviceId) == unitname2service_map.end()) { - vLog(LOG_WARN, "下发了一个不存在services的控制设备id<%s>。\n", deviceId.c_str()); - return false; - } - name2servicemap name2service_map = unitname2service_map[deviceId]; - if (name2service_map.find(serviceName) == name2service_map.end()) { - vLog(LOG_WARN, "下发了一个不存在的service名称<%s>。\n", serviceName.c_str()); - return false; - } - - struct_service_item item = name2service_map[serviceName]; - - int operType = item.type; - int uid = item.uid; - int point = item.point; - - if (operType == CMD_CONTROL_OPERATION) { //遥控 - if (point < 0) { - vLog(LOG_ERROR, "未能找到对应的遥控点号,请检查并确认。\n"); - return FALSE; - } - int operValue = jsonRoot["opValue"].asInt(); - SetUnitYK(uid, point, (operValue & 0x03), YKS_SELREQ, YKR_IDLE); - vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE.\n", uid, point, ((operValue & 0x03) ? "CLOSE" : "TRIP")); - } else if (operType == CMD_CONTROL_SETTING) { //遥调 - union { - float fval; - DWORD dval; - } operValue; - if (point < 0) { - vLog(LOG_ERROR, "未能找到对应的遥调点号,请检查并确认。\n"); - return FALSE; - } - if (jsonRoot["opValue"].isInt()) operValue.dval = jsonRoot["opValue"].asInt(); - else if (jsonRoot["opValue"].isDouble()) operValue.fval = jsonRoot["opValue"].asFloat(); - SetUnitYT(uid, point, operValue.dval, YTS_EXEREQ, YTR_IDLE); - vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE.\n", uid, point, operValue.dval); - } else { - vLog(LOG_ERROR, "平台下发的<%d>命令错误。operType不是<0-遥控或1-遥调>,系统不支持的命令!\n", operType); - return FALSE; - } - - return TRUE; -} - -static BOOLEAN processUartParam(const Json::Value jsonRoot, int ord) -{ - if (ord < 0 || ord >= HARDWARE_PORTS_NUM) return FALSE; - - config_config.hardware.ports[ord].state = TRUE; - snprintf(config_config.hardware.ports[ord].name, sizeof(config_config.hardware.ports[ord].name), "ttyS%d", ord); - config_config.hardware.ports[ord].baud = 9600; - config_config.hardware.ports[ord].data = 8; - config_config.hardware.ports[ord].parity = 0; - config_config.hardware.ports[ord].stop = 0; - config_config.hardware.ports[ord].timeout = 1000; - - if (jsonRoot["name"].isString()) { - snprintf(config_config.hardware.ports[ord].name, sizeof(config_config.hardware.ports[ord].name), "%s", jsonRoot["name"].asCString()); - } - if (jsonRoot["baud"].isInt()) { - config_config.hardware.ports[ord].baud = jsonRoot["baud"].asInt(); - } else if (jsonRoot["baud"].isString()) { - config_config.hardware.ports[ord].baud = atoi(jsonRoot["baud"].asCString()); - } - if (jsonRoot["data"].isInt()) { - config_config.hardware.ports[ord].data = jsonRoot["data"].asInt(); - } else if (jsonRoot["data"].isString()) { - config_config.hardware.ports[ord].data = atoi(jsonRoot["data"].asCString()); - } - if (jsonRoot["parity"].isInt()) { - config_config.hardware.ports[ord].parity = jsonRoot["parity"].asInt(); - } else if (jsonRoot["parity"].isString()) { - config_config.hardware.ports[ord].parity = atoi(jsonRoot["parity"].asCString()); - } - if (jsonRoot["stop"].isInt()) { - if (jsonRoot["stop"].asInt() == 1) config_config.hardware.ports[ord].stop = 0; - else if (jsonRoot["stop"].asInt() == 2) config_config.hardware.ports[ord].stop = 2; - } else if (jsonRoot["stop"].isString()) { - if (jsonRoot["stop"].asString() == "1") config_config.hardware.ports[ord].stop = 0; - else if (jsonRoot["stop"].asString() == "2") config_config.hardware.ports[ord].stop = 2; - } - if (jsonRoot["timeout"].isInt()) { - config_config.hardware.ports[ord].timeout = jsonRoot["timeout"].asInt(); - } else if (jsonRoot["timeout"].isString()) { - config_config.hardware.ports[ord].timeout = atoi(jsonRoot["timeout"].asCString()); - } - - return TRUE; -} - -static BOOLEAN processNetworkParam(const Json::Value jsonRoot, int pid) -{ - if (pid < 0 || pid >= PROCESSES_NUM) return FALSE; - - config_config.processes[pid].option.network.ignored_source = TRUE; - config_config.processes[pid].option.network.socket_type = SOCK_STREAM; - config_config.processes[pid].option.network.bind_addr = INADDR_ANY; - config_config.processes[pid].option.network.bind_port = 0; - config_config.processes[pid].option.network.target_addr = INADDR_ANY; - config_config.processes[pid].option.network.target_port = 502; - - if (jsonRoot["targetAddr"].isInt()) { - config_config.processes[pid].option.network.target_addr = jsonRoot["targetAddr"].asInt(); - } else if (jsonRoot["targetAddr"].isString()) { - if (inet_pton(AF_INET, jsonRoot["targetAddr"].asCString(), &config_config.processes[pid].option.network.target_addr) == 1) { - vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.network.target_addr); - } else { - vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno)); - } - } - if (jsonRoot["targetPort"].isInt()) { - config_config.processes[pid].option.network.target_port = jsonRoot["targetPort"].asInt(); - } else if (jsonRoot["targetPort"].isString()) { - config_config.processes[pid].option.network.target_port = atoi(jsonRoot["targetPort"].asCString()); - } - - return TRUE; -} - -static BOOLEAN processHostIEC104ProcessParam(const Json::Value jsonRoot, int pid) -{ - if (pid < 0 || pid >= PROCESSES_NUM) return FALSE; - - config_config.processes[pid].option.iec104.net.ignored_source = TRUE; - config_config.processes[pid].option.iec104.net.socket_type = SOCK_STREAM; - config_config.processes[pid].option.iec104.net.target_addr = INADDR_ANY; - config_config.processes[pid].option.iec104.net.target_port = 2404; - config_config.processes[pid].option.iec104.asdu_addr_size = 2; - config_config.processes[pid].option.iec104.cot_size = 2; - config_config.processes[pid].option.iec104.info_addr_size = 3; - config_config.processes[pid].option.iec104.t0 = 30; - config_config.processes[pid].option.iec104.t1 = 15; - config_config.processes[pid].option.iec104.t2 = 10; - config_config.processes[pid].option.iec104.t3 = 20; - config_config.processes[pid].option.iec104.k = 12; - config_config.processes[pid].option.iec104.w = 8; - - if (jsonRoot["host"].isInt()) { - config_config.processes[pid].option.iec104.net.target_addr = jsonRoot["host"].asInt(); - } else if (jsonRoot["host"].isString()) { - if (inet_pton(AF_INET, jsonRoot["host"].asCString(), &config_config.processes[pid].option.iec104.net.target_addr) == 1) { - vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.iec104.net.target_addr); - } else { - vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno)); - } - } - if (jsonRoot["port"].isInt()) { - config_config.processes[pid].option.iec104.net.target_port = jsonRoot["port"].asInt(); - } else if (jsonRoot["port"].isString()) { - config_config.processes[pid].option.iec104.net.target_port = atoi(jsonRoot["port"].asCString()); - } - if (jsonRoot["t0"].isInt()) { - config_config.processes[pid].option.iec104.t0 = jsonRoot["t0"].asInt(); - } else if (jsonRoot["t0"].isString()) { - config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t0"].asCString()); - } - if (jsonRoot["t1"].isInt()) { - config_config.processes[pid].option.iec104.t0 = jsonRoot["t1"].asInt(); - } else if (jsonRoot["t1"].isString()) { - config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t1"].asCString()); - } - if (jsonRoot["t2"].isInt()) { - config_config.processes[pid].option.iec104.t0 = jsonRoot["t2"].asInt(); - } else if (jsonRoot["t2"].isString()) { - config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t2"].asCString()); - } - if (jsonRoot["t3"].isInt()) { - config_config.processes[pid].option.iec104.t0 = jsonRoot["t3"].asInt(); - } else if (jsonRoot["t3"].isString()) { - config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t3"].asCString()); - } - - return TRUE; -} - - -#define POINT_TYPE_YX 0 -#define POINT_TYPE_YC 1 -#define POINT_TYPE_YM 2 -#define POINT_TYPE_YK 3 -#define POINT_TYPE_YT 4 - -BOOLEAN processModbusPointParam(const Json::Value jsonRoot, int uid, int point, int type) -{ - if (uid < 0 || uid >= UNIT_NUM) return FALSE; - if (point < 0) return FALSE; - switch (type) - { - case POINT_TYPE_YX: - if (point >= config_config.units[uid].yxcount) return FALSE; - if (jsonRoot["col1"].isString()) { - BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); - config_config.units[uid].yxs[point].m_param[0] = funcCode; - } else if (jsonRoot["col1"].isInt()) { - BYTE funcCode = (BYTE)jsonRoot["col1"].asInt(); - config_config.units[uid].yxs[point].m_param[0] = funcCode; - } else { - config_config.units[uid].yxs[point].m_param[0] = 0; - } - if (jsonRoot["col2"].isString()) { - BYTE offSet = (BYTE)atoi(jsonRoot["col2"].asCString()); - config_config.units[uid].yxs[point].m_param[3] = offSet; - } if (jsonRoot["col2"].isInt()) { - BYTE offSet = (BYTE)jsonRoot["col2"].asInt(); - config_config.units[uid].yxs[point].m_param[3] = offSet; - } else { - config_config.units[uid].yxs[point].m_param[3] = 0; - } - if (jsonRoot["col3"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col3"].asCString()); - config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff); - config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col3"].isInt()) { - WORD registerAddr = (WORD)jsonRoot["col3"].asInt(); - config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff); - config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff); - } else { - config_config.units[uid].yxs[point].m_param[1] = 0; - config_config.units[uid].yxs[point].m_param[2] = 0; - } - break; - case POINT_TYPE_YC: - if (point >= config_config.units[uid].yccount) return FALSE; - if (jsonRoot["col1"].isString()) { - BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); - config_config.units[uid].ycs[point].m_param[0] = funcCode; - } else if (jsonRoot["col1"].isInt()) { - BYTE funcCode = jsonRoot["col1"].asInt(); - config_config.units[uid].ycs[point].m_param[0] = funcCode; - } else { - config_config.units[uid].ycs[point].m_param[0] = 0; - } - if (jsonRoot["col3"].isString()) { - BYTE dataType = (BYTE)atoi(jsonRoot["col3"].asCString()); - config_config.units[uid].ycs[point].m_param[4] = dataType; - if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1; - else config_config.units[uid].ycs[point].m_param[3] = 2; - } else if (jsonRoot["col3"].isInt()) { - BYTE dataType = jsonRoot["col3"].asInt(); - config_config.units[uid].ycs[point].m_param[4] = dataType; - if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1; - else config_config.units[uid].ycs[point].m_param[3] = 2; - } else { - config_config.units[uid].ycs[point].m_param[4] = 0; - config_config.units[uid].ycs[point].m_param[3] = 1; - } - if (jsonRoot["col2"].isString()) { - BYTE signMark = (BYTE)atoi(jsonRoot["col2"].asCString()); - config_config.units[uid].ycs[point].m_param[5] = signMark; - } else if (jsonRoot["col2"].isInt()) { - BYTE signMark = jsonRoot["col2"].asInt(); - config_config.units[uid].ycs[point].m_param[5] = signMark; - } else { - config_config.units[uid].ycs[point].m_param[5] = 0; - } - if (jsonRoot["col4"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); - config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff); - config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff); - } else if (jsonRoot["col4"].isInt()) { - WORD registerAddr = (WORD)jsonRoot["col4"].asInt(); - config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff); - config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff); - } else { - config_config.units[uid].ycs[point].m_param[1] = 0; - config_config.units[uid].ycs[point].m_param[2] = 0; - } - break; - case POINT_TYPE_YM: - if (point >= config_config.units[uid].ymcount) return FALSE; - if (jsonRoot["col1"].isString()) { - BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); - config.units[uid].yms[point].m_param[0] = funcCode; - } else { - config.units[uid].yms[point].m_param[0] = 0; - } - if (jsonRoot["col2"].isString()) { - BYTE dataType = (BYTE)atoi(jsonRoot["col2"].asCString()); - config.units[uid].yms[point].m_param[4] = dataType; - if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1; - if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4; - else config.units[uid].yms[point].m_param[3] = 2; - } else { - config.units[uid].yms[point].m_param[4] = 0; - config.units[uid].yms[point].m_param[3] = 1; - } - if (jsonRoot["col4"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); - config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff); - config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff); - } else { - config.units[uid].yms[point].m_param[1] = 0; - config.units[uid].yms[point].m_param[2] = 0; - } - break; - case POINT_TYPE_YK: - if (point >= config_config.units[uid].ykcount) return FALSE; - config_config.units[uid].yks[point].m_param[1] = 0; - config_config.units[uid].yks[point].m_param[2] = 0; - config_config.units[uid].yks[point].m_param[4] = 0xFF; - config_config.units[uid].yks[point].m_param[5] = 0xFF; - config_config.units[uid].yks[point].m_param[8] = 0xFF; - config_config.units[uid].yks[point].m_param[9] = 0xFF; - config_config.units[uid].yks[point].m_param[12] = 0xFF; - config_config.units[uid].yks[point].m_param[13] = 0xFF; - config_config.units[uid].yks[point].m_param[16] = 0xFF; - config_config.units[uid].yks[point].m_param[17] = 0xFF; - if (jsonRoot["col1"].isString()) { - BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); - config_config.units[uid].yks[point].m_param[0] = funcCode; - } if (jsonRoot["col1"].isInt()) { - BYTE funcCode = (BYTE)jsonRoot["col1"].asInt(); - config_config.units[uid].yks[point].m_param[0] = funcCode; - } else { - config_config.units[uid].yks[point].m_param[0] = 0; - } - if (jsonRoot["col4"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); - config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); - config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col4"].isInt()) { - WORD registerAddr = (WORD)jsonRoot["col4"].asInt(); - config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); - config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } else { - config_config.units[uid].yks[point].m_param[6] = 0xFF; - config_config.units[uid].yks[point].m_param[7] = 0xFF; - } - if (jsonRoot["col6"].isString()) { - WORD closeVal = (WORD)atoi(jsonRoot["col6"].asCString()); - config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); - config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); - } if (jsonRoot["col6"].isInt()) { - WORD closeVal = (WORD)jsonRoot["col6"].asInt(); - config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); - config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); - } else { - config_config.units[uid].yks[point].m_param[10] = 0xFF; - config_config.units[uid].yks[point].m_param[11] = 0xFF; - } - if (jsonRoot["col8"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col8"].asCString()); - config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); - config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col8"].isInt()) { - WORD registerAddr = (WORD)jsonRoot["col8"].asInt(); - config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); - config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); - } else { - config_config.units[uid].yks[point].m_param[14] = 0xFF; - config_config.units[uid].yks[point].m_param[15] = 0xFF; - } - if (jsonRoot["col10"].isString()) { - WORD openVal = (WORD)atoi(jsonRoot["col10"].asCString()); - config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); - config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); - } if (jsonRoot["col10"].isInt()) { - WORD openVal = (WORD)jsonRoot["col10"].asInt(); - config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); - config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); - } else { - config_config.units[uid].yks[point].m_param[18] = 0xFF; - config_config.units[uid].yks[point].m_param[19] = 0xFF; - } - break; - case POINT_TYPE_YT: - if (point >= config_config.units[uid].ytcount) return FALSE; - config_config.units[uid].yts[point].m_param[2] = 0; - config_config.units[uid].yts[point].m_param[4] = 0xFF; - config_config.units[uid].yts[point].m_param[5] = 0xFF; - config_config.units[uid].yts[point].m_param[8] = 0xFF; - config_config.units[uid].yts[point].m_param[9] = 0xFF; - if (jsonRoot["col1"].isString()) { - BYTE nSetType = (BYTE)atoi(jsonRoot["col1"].asCString()); - config_config.units[uid].yts[point].m_param[0] = nSetType; - } if (jsonRoot["col1"].isInt()) { - BYTE nSetType = (BYTE)jsonRoot["col1"].asInt(); - config_config.units[uid].yts[point].m_param[0] = nSetType; - } else { - config_config.units[uid].yts[point].m_param[0] = 0; - } - if (jsonRoot["col2"].isString()) { - BYTE funcCode = (BYTE)atoi(jsonRoot["col2"].asCString()); - config_config.units[uid].yts[point].m_param[1] = funcCode; - } if (jsonRoot["col2"].isInt()) { - BYTE funcCode = (BYTE)jsonRoot["col2"].asInt(); - config_config.units[uid].yts[point].m_param[1] = funcCode; - } else { - config_config.units[uid].yts[point].m_param[1] = 0; - } - if (jsonRoot["col5"].isString()) { - WORD registerAddr = (WORD)atoi(jsonRoot["col5"].asCString()); - config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); - config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col5"].isInt()) { - WORD registerAddr = (WORD)jsonRoot["col5"].asInt(); - config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); - config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } else { - config_config.units[uid].yts[point].m_param[6] = 0xFF; - config_config.units[uid].yts[point].m_param[7] = 0xFF; - } - break; - default: break; - } - - return TRUE; -} - -static bool dealConfigFile(const Json::Value jsonRoot) -{ - bool result = false; - do { - FILE* pf = fopen("aaa.json", "w+"); - if (pf) { - fwrite(jsonRoot.toStyledString().c_str(), jsonRoot.toStyledString().length(), 1, pf); - fclose(pf); - } - if (!configInitializeMemory()) { - vLog(LOG_ERROR, "Fail initialize memory!\n"); - break; - } - if (!jsonRoot["nodeId"].isString()) { - vLog(LOG_ERROR, "配置文件格式错误,缺少节点ID的配置信息,请检查。\n"); - break; - } - if (jsonRoot["version"].isNull()) { - vLog(LOG_WARN, "配置文件格式错误,缺少版本信息,请检查。\n"); - } - if (jsonRoot["version"].isInt()) { - snprintf(config_system32.version, sizeof(config_system32.version), "%d", jsonRoot["version"].asInt()); - } else if (jsonRoot["version"].isString()) { - snprintf(config_system32.version, sizeof(config_system32.version), "%s", jsonRoot["version"].asCString()); - } - - //更新节点配置 - config_nodes.m_node[0].m_netnode_no = 0; - config_nodes.m_node[0].m_tcitype = 1; - config_nodes.m_node[0].m_target_addr = INADDR_LOOPBACK; - config_nodes.m_node[0].m_target_port = 15000; - snprintf(config_nodes.m_node[0].m_machine_name, sizeof(config_nodes.m_node[0].m_machine_name), "%s", jsonRoot["nodeId"].asCString()); - //更新链路配置文件 - const Json::Value links = jsonRoot["links"]; - int count = links.size(); - int uartId = 0; - - //m_gLinkIDs.clear(); - uid2pid_map.clear(); - for (int i = 0; i < count; i++) { - const Json::Value link = links[i]; - - config_config.processes[i].state = TRUE; - config_config.processes[i].type = MASTER_UNIT; - config_config.processes[i].time_gap = 300; //默认参数 - config_config.processes[i].poll_gap = 5; - config_config.processes[i].mode = PROCESS_MODE_MASTER; - - if (link["linkName"].isString()) { - snprintf(config_config.processes[i].name, sizeof(config_config.processes[i].name), "%s", link["linkName"].asCString()); - } - if (link["linkId"].isString()) { - config_config.processes[i].irn = strtoll(link["linkId"].asCString(), NULL, 10); - } - if (link["protocol"].isInt()) { - config_config.processes[i].proto = link["protocol"].asInt(); - } - - //处理链路参数,根据协议参数的不同来处理 - const Json::Value params = link["params"]; - if (!params.isNull()) { - switch (config_config.processes[i].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - processUartParam(params, uartId); - config_config.processes[i].order = uartId++; - break; - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processNetworkParam(params, i); - break; - case PROTOCOL_HOST_IEC104: - processHostIEC104ProcessParam(params, i); - break; - } - } - //处理链接设备 - const Json::Value devices = link["devices"]; - if (devices.isArray()) { - int size = devices.size(); - for (int j = 0; j < size; j++) { - std::string id = devices[j].asCString(); - if (uid2pid_map.find(id) == uid2pid_map.end()) { - uid2pid_map.insert(uid2pidmap::value_type(id, i)); - } - } - } - } - - //更新设备列表 - const Json::Value equipments = jsonRoot["equipments"]; - { - long yxorder = 0, ycorder = 0, ymorder = 0, ykorder = 0, ytorder = 0; - char dbyxname[512]; - snprintf(dbyxname, sizeof(dbyxname), "%s/%s", configpath, FILE_DATABASE_YX_STATIC); - FILE *pfdbyxname = fopen(dbyxname, "wb+"); - char dbycname[512]; - snprintf(dbycname, sizeof(dbycname), "%s/%s", configpath, FILE_DATABASE_YC_STATIC); - FILE *pfdbycname = fopen(dbycname, "wb+"); - char dbymname[512]; - snprintf(dbymname, sizeof(dbymname), "%s/%s", configpath, FILE_DATABASE_YM_STATIC); - FILE *pfdbymname = fopen(dbymname, "wb+"); - char dbykname[512]; - snprintf(dbykname, sizeof(dbykname), "%s/%s", configpath, FILE_DATABASE_YK_STATIC); - FILE *pfdbykname = fopen(dbykname, "wb+"); - char dbytname[512]; - snprintf(dbytname, sizeof(dbytname), "%s/%s", configpath, FILE_DATABASE_YT_STATIC); - FILE *pfdbytname = fopen(dbytname, "wb+"); - - int count = equipments.size(); - for (int i = 0; i < count; i++) { - const Json::Value equipment = equipments[i]; - int uid = i; - short pid = -1; - - snprintf(config_static_units[uid].name, sizeof(config_static_units[uid].name), "device_%d", uid); - snprintf(config_static_units[uid].model, sizeof(config_static_units[uid].model), "model_%d", uid); - snprintf(config_static_units[uid].manufacturerId, sizeof(config_static_units[uid].manufacturerId), "%s", "iss"); - - std::string id = ""; - std::string address = ""; - if (equipment["id"].isString()) { - id = equipment["id"].asString(); - snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "%s", id.c_str()); - } else { - snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "iss_%d", uid); - } - if (equipment["addr"].isString()) { - address = equipment["addr"].asString(); - } - if (uid2pid_map.find(id) != uid2pid_map.end()) { - pid = uid2pid_map[id]; - if (pid < 0 || pid >= PROCESSES_NUM) continue; - for (int u = 0; u < PROCESS_UNIT_NUM; u++) { - if (config_config.processes[pid].units[u] < 0) { - config_config.processes[pid].units[u] = uid; - break; - } - } - //根据协议修改地址 - if (address != "") { - BYTE addrType = ADDR_TYPE_NORMAL; //根据协议设定单元地址类型 - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - break; - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - addrType = ADDR_TYPE_IPV4; - break; - case PROTOCOL_HOST_IEC104: - addrType = ADDR_TYPE_IPV4_FACNO; - break; - } - if (addrType == ADDR_TYPE_HEX) { - StringToHex(address.c_str(), config_config.units[uid].addr); - } else if (addrType == ADDR_TYPE_IPV4) { - DWORD addr; - inet_pton(AF_INET, address.c_str(), (struct in_addr*)&addr); - memcpy(config_config.units[uid].addr, &addr, sizeof(addr)); - } else if (addrType == ADDR_TYPE_IPV4_FACNO) { - std::vector tokens = split(address, ':'); - if (tokens.size() >= 2) { - DWORD addr; - inet_pton(AF_INET, tokens.at(0).c_str(), (struct in_addr*)&addr); - memcpy(config_config.units[uid].addr, &addr, sizeof(addr)); - addr = (DWORD)atoi(tokens.at(1).c_str()); - memcpy(&config_config.units[uid].addr[4], &addr, sizeof(addr)); - } else { - DWORD addr; - inet_pton(AF_INET, tokens.at(0).c_str(), (struct in_addr*)&addr); - memcpy(config_config.units[uid].addr, &addr, sizeof(addr)); - addr = 1; - memcpy(&config_config.units[uid].addr[4], &addr, sizeof(addr)); - } - } else { - DWORD addr = (DWORD)atoi(address.c_str()); - memcpy(config_config.units[uid].addr, &addr, sizeof(addr)); - } - } - } else { - vLog(LOG_DEBUG, "该链路上连接的设备ID<%s>不在设备列表中,请检查后重新下发.\n", id.c_str()); - } - - attrvector yxs, ycs, yms, yks, yts; - const Json::Value attrs = equipment["attrs"]; - if (!attrs.isNull()) { - int size = attrs.size(); - for (int j = 0; j < size; j++) { - const Json::Value attr = attrs[j]; - std::string type = ""; - if (attr["type"].isString()) type = attr["type"].asString(); - struct_attr name_param; - name_param.name = ""; - if (attr["name"].isString()) name_param.name = attr["name"].asString(); - if (attr["params"].isObject()) name_param.value = attr["params"]; - if (type == "yc") ycs.push_back(name_param); - else if (type == "yx") yxs.push_back(name_param); - else if (type == "ym") yms.push_back(name_param); - } - } - const Json::Value services = equipment["services"]; - if (!services.isNull()) { - int size = services.size(); - for (int j = 0; j < size; j++) { - const Json::Value service = services[j]; - std::string type = ""; - if (service["type"].isString()) type = service["type"].asString(); - struct_attr name_param; - name_param.name = ""; - if (service["name"].isString()) name_param.name = service["name"].asString(); - if (service["params"].isObject()) name_param.value = service["params"]; - if (type == "yk") yks.push_back(name_param); - else if (type == "yt") yts.push_back(name_param); - } - } - config_config.units[uid].value = SPI_ON; - config_config.units[uid].softdog = UNIT_WATCHDOG_TIME; - - config_config.units[uid].state = TRUE; - config_config.units[uid].type = MASTER_UNIT; - config_config.units[uid].yxcount = yxs.size(); - config_config.units[uid].yccount = ycs.size(); - config_config.units[uid].ymcount = yms.size(); - config_config.units[uid].ykcount = yks.size(); - config_config.units[uid].ytcount = yts.size(); - - if (config_config.units[uid].yccount > 0) { - config_config.units[uid].ycs = new struUnitYC[config_config.units[uid].yccount]; - if (NULL != config_config.units[uid].ycs) { - memset(config_config.units[uid].ycs, 0, sizeof(struUnitYC) * config_config.units[uid].yccount); - for (int k = 0; k < config_config.units[uid].yccount; k++) { - snprintf(config_config.units[uid].ycs[k].name, sizeof(config_config.units[uid].ycs[k].name), "%s", ycs[k].name.c_str()); - config_config.units[uid].ycs[k].order = ycorder++; - config_config.units[uid].ycs[k].value = 0; - config_config.units[uid].ycs[k].qds = 0x80; //默认为无效 - config_config.units[uid].ycs[k].factor = 1; - config_config.units[uid].ycs[k].change_pos = 2; - config_config.units[uid].ycs[k].coef = 1.0f; - config_config.units[uid].ycs[k].base = 0; - config_config.units[uid].ycs[k].upBound = 9999999.999f; - config_config.units[uid].ycs[k].lowBound = -9999999.999f; - config_config.units[uid].ycs[k].limit1Enable = FALSE; - config_config.units[uid].ycs[k].limit1Low = 0; - config_config.units[uid].ycs[k].limit1High = 0.0f; - config_config.units[uid].ycs[k].limit2Enable = FALSE; - config_config.units[uid].ycs[k].limit2Low = 0; - config_config.units[uid].ycs[k].limit2High = 0.0f; - Json::Value param = ycs[k].value; - if (!param.isNull()) { - if (param["coef"].isDouble()) config_config.units[uid].ycs[k].coef = param["coef"].asFloat(); - if (param["base"].isDouble()) config_config.units[uid].ycs[k].base = param["base"].asFloat(); - if (param["upBound"].isDouble()) config_config.units[uid].ycs[k].upBound = param["upBound"].asFloat(); - if (param["lowBound"].isDouble()) config_config.units[uid].ycs[k].lowBound = param["lowBound"].asFloat(); - if (param["limit1Enable"].isInt()) config_config.units[uid].ycs[k].limit1Enable = param["limit1Enable"].asInt(); - if (param["limit2Enable"].isInt()) config_config.units[uid].ycs[k].limit2Enable = param["limit2Enable"].asInt(); - if (param["limit1Low"].isDouble()) config_config.units[uid].ycs[k].limit1Low = param["limit1Low"].asFloat(); - if (param["limit2Low"].isDouble()) config_config.units[uid].ycs[k].limit2Low = param["limit2Low"].asFloat(); - if (param["limit1High"].isDouble()) config_config.units[uid].ycs[k].limit1High = param["limit1High"].asFloat(); - if (param["limit2High"].isDouble()) config_config.units[uid].ycs[k].limit2High = param["limit2High"].asFloat(); - - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processModbusPointParam(param, uid, k, POINT_TYPE_YC); - break; - case PROTOCOL_HOST_IEC104: - break; - } - } - if (config_config.units[uid].type == MASTER_UNIT) { - config_database.ycs[config_config.units[uid].ycs[k].order].coef = config_config.units[uid].ycs[k].coef; - config_database.ycs[config_config.units[uid].ycs[k].order].base = config_config.units[uid].ycs[k].base; - } - if (pfdbycname) { - fseek(pfdbycname, sizeof(struYCStatic) * config_config.units[uid].ycs[k].order, SEEK_SET); - fwrite(ycs[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbycname); - } - } - } - } - if (config_config.units[uid].ymcount > 0) { - config_config.units[uid].yms = new struUnitYM[config_config.units[uid].ymcount]; - if (NULL != config_config.units[uid].yms) { - memset(config_config.units[uid].yms, 0, sizeof(struUnitYM) * config_config.units[uid].ymcount); - for (int k = 0; k < config_config.units[uid].ymcount; k++) { - snprintf(config_config.units[uid].yms[k].name, sizeof(config_config.units[uid].yms[k].name), "%s", yms[k].name.c_str()); - config_config.units[uid].yms[k].order = ymorder++; - config_config.units[uid].yms[k].value = 0; - config_config.units[uid].yms[k].coef = 1.0f; - config_config.units[uid].yms[k].base = 0; - - Json::Value param = yms[k].value; - if (!param.isNull()) { - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processModbusPointParam(param, uid, k, POINT_TYPE_YM); - break; - case PROTOCOL_HOST_IEC104: - break; - } - } - if (config_config.units[uid].type == MASTER_UNIT) { - config_database.yms[config_config.units[uid].yms[k].order].coef = config_config.units[uid].yms[k].coef; - config_database.yms[config_config.units[uid].yms[k].order].base = config_config.units[uid].yms[k].base; - } - - if (pfdbymname) { - fseek(pfdbymname, sizeof(struYMStatic) * config_config.units[uid].yms[k].order, SEEK_SET); - fwrite(yms[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbymname); - } - } - } - } - if (config_config.units[uid].ykcount > 0) { - config_config.units[uid].yks = new struUnitYK[config_config.units[uid].ykcount]; - if (NULL != config_config.units[uid].yks) { - memset(config_config.units[uid].yks, 0, sizeof(struUnitYK) * config_config.units[uid].ykcount); - for (int k = 0; k < config_config.units[uid].ykcount; k++) { - snprintf(config_config.units[uid].yks[k].name, sizeof(config_config.units[uid].yks[k].name), "%s", yks[k].name.c_str()); - config_config.units[uid].yks[k].order = ykorder++; - - Json::Value param = yks[k].value; - if (!param.isNull()) { - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processModbusPointParam(param, uid, k, POINT_TYPE_YK); - break; - case PROTOCOL_HOST_IEC104: - break; - } - } - if (pfdbykname) { - fseek(pfdbykname, sizeof(struYKStatic) * config_config.units[uid].yks[k].order, SEEK_SET); - fwrite(yks[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbykname); - } - } - } - } - if (config_config.units[uid].ytcount > 0) { - config_config.units[uid].yts = new struUnitYT[config_config.units[uid].ytcount]; - if (NULL != config_config.units[uid].yts) { - memset(config_config.units[uid].yts, 0, sizeof(struUnitYT) * config_config.units[uid].ytcount); - for (int k = 0; k < config_config.units[uid].ytcount; k++) { - snprintf(config_config.units[uid].yts[k].name, sizeof(config_config.units[uid].yts[k].name), "%s", yts[k].name.c_str()); - config_config.units[uid].yts[k].order = ytorder++; - - Json::Value param = yts[k].value; - if (!param.isNull()) { - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processModbusPointParam(param, uid, k, POINT_TYPE_YT); - break; - case PROTOCOL_HOST_IEC104: - break; - } - } - if (pfdbytname) { - fseek(pfdbytname, sizeof(struYTStatic) * config_config.units[uid].yts[k].order, SEEK_SET); - fwrite(yts[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbytname); - } - } - } - } - if (config_config.units[uid].yxcount > 0) { - config_config.units[uid].yxs = new struUnitYX[config_config.units[uid].yxcount]; - if (NULL != config_config.units[uid].yxs) { - memset(config_config.units[uid].yxs, 0, sizeof(struUnitYX) * config_config.units[uid].yxcount); - for (int k = 0; k < config_config.units[uid].yxcount; k++) { - snprintf(config_config.units[uid].yxs[k].name, sizeof(config_config.units[uid].yxs[k].name), "%s", yxs[k].name.c_str()); - config_config.units[uid].yxs[k].order = yxorder++; - config_config.units[uid].yxs[k].value = 0; - config_config.units[uid].yxs[k].qds = 0x80; //默认为无效 - config_config.units[uid].yxs[k].invert = 0; - config_database.yxs[config_config.units[uid].yxs[k].order].auto_reset = 0; - - Json::Value param = yxs[k].value; - if (!param.isNull()) { - if (param["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt(); - switch (config_config.processes[pid].proto) { - case PROTOCOL_HOST_MODBUS_RTU: - case PROTOCOL_HOST_MODBUS_TCP: - case PROTOCOL_HOST_MODBUS_RTU_TCP: - processModbusPointParam(param, uid, k, POINT_TYPE_YX); - break; - case PROTOCOL_HOST_IEC104: - break; - } - } - if (pfdbyxname) { - fseek(pfdbyxname, sizeof(struYKStatic) * config_config.units[uid].yxs[k].order, SEEK_SET); - fwrite(yxs[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbyxname); - } - } - } - } - } - if (pfdbyxname) fclose(pfdbyxname); - if (pfdbycname) fclose(pfdbycname); - if (pfdbymname) fclose(pfdbymname); - if (pfdbykname) fclose(pfdbykname); - if (pfdbytname) fclose(pfdbytname); - } - - #if 0 - { - int pid = PROCESSES_NUM - 1; - int uid = UNIT_NUM - 1; - - config_config.processes[pid].state = TRUE; - snprintf(config_config.processes[pid].name, sizeof(config_config.processes[pid].name), "localDebug"); - config_config.processes[pid].type = TRUE; - config_config.processes[pid].time_accept = TRUE; //accept set time command from this proc - config_config.processes[pid].proto = PROTOCOL_LOCAL_DEBUG; - config_config.processes[pid].order = 0; //CARD or PORT order - config_config.processes[pid].mode = 1; //slave mode or master mode or duplex mode - config_config.processes[pid].time_gap = 300; //send out time from this proc 18.2c/s - config_config.processes[pid].poll_gap = 5; //send out command 18.2c/s - config_config.processes[pid].softdog = 0; //software watchdog counter - config_config.processes[pid].units[0] = uid; - config_config.processes[pid].option.network.ignored_source = TRUE; - config_config.processes[pid].option.network.socket_type = SOCK_STREAM; - config_config.processes[pid].option.network.bind_addr = INADDR_ANY; - config_config.processes[pid].option.network.bind_port = 9000; - config_config.processes[pid].option.network.target_addr = INADDR_ANY; - config_config.processes[pid].option.network.target_port = 0; - - config_config.units[uid].state = TRUE; - config_config.units[uid].type = 1; - config_config.units[uid].addr[0] = 0; - memset(config_config.units[uid].m_param, 0, sizeof(config_config.units[uid].m_param)); //每个单元有256个字节的参数。 - config_config.units[uid].yxcount = 0; - config_config.units[uid].yccount = 0; - config_config.units[uid].ymcount = 0; - config_config.units[uid].ykcount = 0; - config_config.units[uid].ytcount = 0; - config_config.units[uid].softdog = 0; - config_config.units[uid].yxbwload = 0; - config_config.units[uid].soeload = 0; - config_config.units[uid].ycbwload = 0; - config_config.units[uid].value = 0; //单元状态 - } - #endif - //保存数据 - configWriteNodeCFG(); - configWriteSystemCFG(); - configWriteHardwareCFG(); - configWriteProcessCFG(); - configWriteUnitCFG(); - configWriteDatabaseCFG(); - //保存静态文件 - configWriteStaticUnitCFG(); //units.sta - - result = true; - } while (0); - - //重启application - if (result) { - g_dataAcquisitionReload = true; - } else { - vLog(LOG_WARN, "配置文件读取失败,请检查后下发!\n"); - } - - return true; -} - -bool OnReceivedSystemAction(noPollConn* conn, const std::string cmdId, const std::string cmd, const Json::Value data) -{ - do { - if (cmd == "configUpdate") { //配置更新 - g_traceId = cmdId; - dealConfigFile(data); - } else if (cmd == "deviceControl") { - g_traceId = cmdId; //response命令的traceId - OnReceivedDeviceCommand(data); - } else { - vLog(LOG_DEBUG, "command: %s is not supported.\n", cmd.c_str()); - } - } while (0); - - return true; -} - -void on_message(noPollConn* conn, const char *msg, const int size) -{ - if (msg == NULL) return; - if (size <= 0) return; - - Json::Value jsonRoot; - jsonRoot.clear(); - std::string err; - Json::CharReaderBuilder builder; - Json::CharReader* reader(builder.newCharReader()); - - vLog(LOG_DEBUG, "Received: %s.\n", msg); - - do { - if (!reader->parse(msg, msg + size, &jsonRoot, &err)) { - vLog(LOG_ERROR, "reader->parse(msg, msg + size, &jsonRoot, &err) error<%d,%s>。\n", errno, err.c_str()); - break; - } - if (jsonRoot["cmd"].isNull()) { - vLog(LOG_ERROR, "json format lost cmd part.\n"); - break; - } - if (jsonRoot["data"].isNull()) { - vLog(LOG_ERROR, "json format lost data part.\n"); - break; - } - std::string cmd = jsonRoot["cmd"].asString(); - std::string cmdId = jsonRoot["cmdId"].asString(); -#if 0 - Json::Int64 mtime = jsonRoot["time"].asInt64(); -#endif - Json::Value datas = jsonRoot["data"]; - OnReceivedSystemAction(conn, cmdId, cmd, datas); - } while (0); -} - -void heart_beat(noPollConn* conn, int status) -{ - //发送心跳报文 - Json::Value payload; - payload["ttl"] = 30000; - payload["status"] = status; - - if (status == 1) { - Json::Value jsonItem; - Json::Value jsonValue; - //for (int i = 0; i < static_cast(m_gLinkIDs.size()); i++) { - for (int i = 0; i < PROCESSES_NUM - 1; i++) { - if (config.processes[i].state == TRUE) { - char linkId[32]; - snprintf(linkId, sizeof(linkId), "%lld", config.processes[i].irn); - jsonValue["linkId"] = linkId; - jsonValue["online"] = (config.processes[i].softdog >= PROCESS_WATCHDOG_TIME) ? false : true; - jsonItem.append(jsonValue); - } - } - if (jsonItem.size() > 0) { - payload["links"] = jsonItem; - } - } - - publish_sensor_data(conn, "", "heartbeat", payload); -} - -bool publishinitDeviceData(noPollConn* conn, int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return false; - - if ((config.units[uid].state & 0x80) != 0x80) { - return false; - } - if ((config.units[uid].state & 0x40) == 0x40) { //该设备已经发送过初始化 - return false; - } - - Json::Value root; - Json::Value values; - - int i; - int count = GetUnitYCCount(uid); - if (count) { - for (i = 0; i < count; i++) { - values[(const char *)config.units[uid].ycs[i].name] = GetUnitYCReal(uid, i); - } - } - count = GetUnitYMCount(uid); - if (count) { - for (i = 0; i < count; i++) { - values[(const char *)config.units[uid].yms[i].name] = GetUnitYMReal(uid, i); - } - } - count = GetUnitYXCount(uid); - if (count) { - for (i = 0; i < count; i++) { - values[(const char *)config.units[uid].yxs[i].name] = GetUnitYX(uid, i); - } - } - if (values.size()) { - root["deviceId"] = static_units[uid].deviceId; - root["values"] = values; - - config.units[uid].state |= 0x40; - return publish_sensor_data(conn, "", "initDeviceData", root); - } - return false; -} - -bool publishAnalogData(noPollConn* conn, int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return false; - Json::Value root; - Json::Value values; - int count = GetUnitYCCount(uid); - if (count) { - for (int i = 0; i < count; i++) { - values[(const char *)config.units[uid].ycs[i].name] = GetUnitYCReal(uid, i); - } - } - if (values.size()) { - root["deviceId"] = static_units[uid].deviceId; - root["values"] = values; - return publish_sensor_data(conn, "", "analogData", root); - } - return false; -} - -bool publishStateData(noPollConn* conn, int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return false; - Json::Value root; - Json::Value values; - int count = GetUnitYXCount(uid); - if (count) { - for (int i = 0; i < count; i++) { - values[(const char *)config.units[uid].yxs[i].name] = GetUnitYX(uid, i); - } - } - if (values.size()) { - root["deviceId"] = static_units[uid].deviceId; - root["values"] = values; - return publish_sensor_data(conn, "", "stateData", root); - } - return false; -} - -bool publishHistoryAnalogData(noPollConn* conn, int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return false; - Json::Value root; - Json::Value values; - if (values.size()) { - root["deviceId"] = static_units[uid].deviceId; - root["values"] = values; - return publish_sensor_data(conn, "", "historyAnalogData", root); - } - return false; -} - -bool publishHistoryStateData(noPollConn* conn, int uid) -{ - if (uid < 0 || uid >= UNIT_NUM) return false; - Json::Value root; - Json::Value values; - if (values.size()) { - root["deviceId"] = static_units[uid].deviceId; - root["values"] = values; - return publish_sensor_data(conn, "", "historyStateData", root); - } - return false; -} - -void releaseAllUnits(void) -{ - for (int i = 0; i < UNIT_NUM; i++) { - if ((config.units[i].state & 0x01) != 0x01) continue; - config.units[i].state &= 0xBF; //0x40取反 - } -} -#endif - pthread_mutex_t mutex; void stop(int signo) @@ -2208,22 +185,9 @@ int main(int argc, char** argv) signal(SIGABRT, stop); signal(SIGFPE, stop); -#ifdef MAIN_FILE - noPollCtx *ctx = nopoll_ctx_new(); - nopoll_log_enable(ctx, nopoll_false); - nopoll_log_color_enable(ctx, nopoll_false); - noPollConn *conn; - DWORD last_connect_sec = 0; -#else CRYDevice ryDevice; -#endif do { -#ifdef MAIN_FILE - int status = 2; //0 - 离线, 1 - 在线, 2 - 未配置 - time_t last_sec = 0; - g_dataAcquisitionReload = false; -#endif vLog(LOG_DEBUG, "system initialize...\n"); char szHostCode[128]; memset(szHostCode, '\0', sizeof(szHostCode)); @@ -2249,68 +213,23 @@ int main(int argc, char** argv) } else { snprintf(version, sizeof(version), "%s", "1"); } -#ifdef MAIN_FILE - unitname2service_map.clear(); - for (int i = 0; i < UNIT_NUM; i++) { - if (config.units[i].state != TRUE) continue; - std::string unit_id = static_units[i].deviceId; - name2servicemap name2service_map; - for (int j = 0; j < config.units[i].ykcount; j++) { - std::string name = config.units[i].yks[j].name; - if (name2service_map.find(name) == name2service_map.end()) { - struct_service_item item; - item.type = CMD_CONTROL_OPERATION; - item.uid = i; - item.point = j; - item.order = config.units[i].yks[j].order; - name2service_map.insert(name2servicemap::value_type(name, item)); - } else { - vLog(LOG_WARN, "同一个设备不能有两个相同的遥控名<%s>,请检查。\n", name.c_str()); - } - } - for (int j = 0; j < config.units[i].ytcount; j++) { - std::string name = config.units[i].yts[j].name; - if (name2service_map.find(name) == name2service_map.end()) { - struct_service_item item; - item.type = CMD_CONTROL_SETTING; - item.uid = i; - item.point = j; - item.order = config.units[i].yts[j].order; - name2service_map.insert(name2servicemap::value_type(name, item)); - } else { - vLog(LOG_WARN, "同一个设备不能有两个相同的遥调名<%s>,请检查。\n", name.c_str()); - } - } - if (unitname2service_map.find(unit_id) == unitname2service_map.end()) { - unitname2service_map.insert(unitname2servicemap::value_type(unit_id, name2service_map)); - } else { - vLog(LOG_WARN, "系统配置了两个相同的设备ID<%s>,请检查。\n", unit_id.c_str()); - } - } - status = 1; -#endif } } if (enable_auto_platform) { -#ifdef MAIN_FILE - //创建WS链接 - if (ctx != NULL) { - nopoll_conn_connect_timeout(ctx, 50000); - char url[512]; - char cPort[64]; - snprintf(url, sizeof(url), "/node/%s/%s", nodeId, version); - snprintf(cPort, sizeof(cPort), "%d", port); - vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, host, cPort); - releaseAllUnits(); - conn = nopoll_conn_new(ctx, host, cPort, NULL, url, NULL, NULL); - //last_connect_sec = system32.timers; - } -#else ryDevice.ry_init(host, port, nodeId, version); -#endif } + //此处增加一条协议配置 +#if 1 + int i; + for (i = 0; i < PROCESSES_NUM; i++) + { + if (config.processes[i].state == FALSE) break; + } + memcpy(&config.processes[i], &config.processes[0], sizeof(struProcess)); + config.processes[i].proto = PROTOCOL_FTP2MINIO; +#endif unsigned int m_runCount = 0; unsigned int count = 0; unsigned int critical = 0; @@ -2336,82 +255,11 @@ int main(int argc, char** argv) } } if (enable_auto_platform) { -#ifdef MAIN_FILE - nopoll_bool isOk = nopoll_conn_is_ready(conn); - if (isOk) { - last_connect_sec = system32.timers; - int msg_count = 0; - noPollMsg *msg[40]; - while ((msg[msg_count] = nopoll_conn_get_msg(conn)) != NULL) { - vLog(LOG_DEBUG, "recv length = %d, %d\n", nopoll_msg_get_payload_size(msg[msg_count]), nopoll_msg_is_final(msg[msg_count])); - if (nopoll_msg_is_final(msg[msg_count])) { - msg_count++; - break; - } else { - msg_count++; - } - } - if (msg_count > 0) { - int buffer_len; - BYTE *buffer = NULL; - if (websocket_msg_join(msg, msg_count, buffer, buffer_len)) { - if (buffer) { - on_message(conn, (const char *)buffer, buffer_len); - delete [] buffer; - buffer = NULL; - } - } - } - for (int i = 0; i < msg_count; i++) { - nopoll_msg_unref(msg[i]); - } - } else { - if (last_connect_sec > 0 && system32.timers > (last_connect_sec + 30)) { - nopoll_conn_connect_timeout(ctx, 50000); - char url[512]; - char cPort[64]; - snprintf(url, sizeof(url), "/node/%s/%s", nodeId, version); - snprintf(cPort, sizeof(cPort), "%d", port); - vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, host, cPort); - releaseAllUnits(); - conn = nopoll_conn_new(ctx, host, cPort, NULL, url, NULL, NULL); - last_connect_sec = system32.timers; - } - } - BOOLEAN sec_changed = FALSE; - if (last_sec != (time_t)system32.timers) { - last_sec = system32.timers; - sec_changed = TRUE; - } - if (sec_changed) { - if ((last_sec % 20) == 0) { - heart_beat(conn, status); - } - } - for (int i = 0; i < UNIT_NUM; i++) { - if ((config.units[i].state & 0x01) != TRUE) continue; - MakeYKFrame(conn, i); - MakeYTFrame(conn, i); - if (sec_changed) { - publishinitDeviceData(conn, i); - if ((last_sec % 60) == 0) { //更新数据 - publishAnalogData(conn, i); - publishStateData(conn, i); - } - } - } -#else if (ryDevice.ry_run()) { break; } -#endif } } -#ifdef MAIN_FILE - if (g_dataAcquisitionReload) { - break; - } -#endif } if (critical > 15) { vLog(LOG_ERROR, "unknow error.\n"); @@ -2428,12 +276,7 @@ int main(int argc, char** argv) if (zlog_inited) zlog_fini(); -#ifdef MAIN_FILE - nopoll_conn_close(conn); - nopoll_ctx_unref(ctx); -#else ryDevice.ry_destroy(); -#endif vLog(LOG_DEBUG, "system stop okay.\n"); return EXIT_SUCCESS; diff --git a/das-dn/cmg/ry.cpp b/das-dn/cmg/ry.cpp index 0c562793..2e00a6c3 100644 --- a/das-dn/cmg/ry.cpp +++ b/das-dn/cmg/ry.cpp @@ -12,17 +12,6 @@ CRYDevice::~CRYDevice() } -std::vector CRYDevice::split(const std::string &s, char delimiter) -{ - std::vector tokens; - std::istringstream tokenStream(s); - std::string token; - while (std::getline(tokenStream, token, delimiter)) { - tokens.push_back(token); - } - return tokens; -} - bool CRYDevice::configInitializeMemory(void) { int i, j; @@ -894,8 +883,20 @@ int CRYDevice::MakeYKFrame(int uid) } else { jsonRoot["result"] = true; } - - publish_sensor_data(m_traceId, "deviceControlResp", jsonRoot); + //查找设备serviceName的traceId + char idName[512]; + snprintf(idName, sizeof(idName), "%s%s", static_units[uid].deviceId, config.units[uid].yks[order].name); + std::string key(idName); + std::string traceId; + if (unitserviceName2cmdId_map.find(key) != unitserviceName2cmdId_map.end()) { + traceId = unitserviceName2cmdId_map[key]; + unitserviceName2cmdId_map.erase(key); + } + else + { + return 0; + } + publish_sensor_data(traceId, "deviceControlResp", jsonRoot); return 1; } return 0; @@ -939,7 +940,20 @@ int CRYDevice::MakeYTFrame(int uid) jsonRoot["result"] = true; } - publish_sensor_data(m_traceId, "deviceControlResp", jsonRoot); + //查找设备serviceName的traceId + char idName[512]; + snprintf(idName, sizeof(idName), "%s%s", static_units[uid].deviceId, config.units[uid].yks[order].name); + std::string key(idName); + std::string traceId; + if (unitserviceName2cmdId_map.find(key) != unitserviceName2cmdId_map.end()) { + traceId = unitserviceName2cmdId_map[key]; + unitserviceName2cmdId_map.erase(key); + } + else + { + return 0; + } + publish_sensor_data(traceId, "deviceControlResp", jsonRoot); return 1; } @@ -976,6 +990,14 @@ bool CRYDevice::OnReceivedDeviceCommand(const Json::Value jsonRoot) return FALSE; } int operValue = jsonRoot["opValue"].asInt(); + //插入信息显示traceId和serviceName的对组关系 + std::string key = deviceId + serviceName; + if (unitserviceName2cmdId_map.find(key) == unitserviceName2cmdId_map.end()) { + unitserviceName2cmdId_map.insert(unitserviceName2cmdIdmap::value_type(key, m_traceId)); + } else { + vLog(LOG_WARN, "系统同时下发了两个相同的serviceName<%s>控制,请检查。\n", serviceName.c_str()); + return false; + } SetUnitYK(uid, point, (operValue & 0x03), YKS_SELREQ, YKR_IDLE); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE.\n", uid, point, ((operValue & 0x03) ? "CLOSE" : "TRIP")); } else if (operType == CMD_CONTROL_SETTING) { //遥调 @@ -989,6 +1011,14 @@ bool CRYDevice::OnReceivedDeviceCommand(const Json::Value jsonRoot) } if (jsonRoot["opValue"].isInt()) operValue.dval = jsonRoot["opValue"].asInt(); else if (jsonRoot["opValue"].isDouble()) operValue.fval = jsonRoot["opValue"].asFloat(); + //插入信息显示traceId和serviceName的对组关系 + std::string key = deviceId + serviceName; + if (unitserviceName2cmdId_map.find(key) == unitserviceName2cmdId_map.end()) { + unitserviceName2cmdId_map.insert(unitserviceName2cmdIdmap::value_type(key, m_traceId)); + } else { + vLog(LOG_WARN, "系统同时下发了两个相同的serviceName<%s>调节,请检查。\n", serviceName.c_str()); + return false; + } SetUnitYT(uid, point, operValue.dval, YTS_EXEREQ, YTR_IDLE); vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE.\n", uid, point, operValue.dval); } else { @@ -1044,32 +1074,141 @@ BOOLEAN CRYDevice::processUartParam(const Json::Value jsonRoot, int ord) return TRUE; } -BOOLEAN CRYDevice::processNetworkParam(const Json::Value jsonRoot, int pid) + +BOOLEAN CRYDevice::processRymodbustcpParam(const Json::Value jsonRoot, int pid) { if (pid < 0 || pid >= PROCESSES_NUM) return FALSE; - config_config.processes[pid].option.network.ignored_source = TRUE; - config_config.processes[pid].option.network.socket_type = SOCK_STREAM; - config_config.processes[pid].option.network.bind_addr = INADDR_ANY; - config_config.processes[pid].option.network.bind_port = 0; - config_config.processes[pid].option.network.target_addr = INADDR_ANY; - config_config.processes[pid].option.network.target_port = 502; + config_config.processes[pid].option.rymodbus.net.ignored_source = TRUE; + config_config.processes[pid].option.rymodbus.net.socket_type = SOCK_STREAM; + config_config.processes[pid].option.rymodbus.net.bind_addr = INADDR_ANY; + config_config.processes[pid].option.rymodbus.net.bind_port = 0; + config_config.processes[pid].option.rymodbus.net.target_addr = INADDR_ANY; + config_config.processes[pid].option.rymodbus.net.target_port = 502; if (jsonRoot["targetAddr"].isInt()) { - config_config.processes[pid].option.network.target_addr = jsonRoot["targetAddr"].asInt(); + config_config.processes[pid].option.rymodbus.net.target_addr = jsonRoot["targetAddr"].asInt(); } else if (jsonRoot["targetAddr"].isString()) { - if (inet_pton(AF_INET, jsonRoot["targetAddr"].asCString(), &config_config.processes[pid].option.network.target_addr) == 1) { - vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.network.target_addr); + if (inet_pton(AF_INET, jsonRoot["targetAddr"].asCString(), &config_config.processes[pid].option.rymodbus.net.target_addr) == 1) { + vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.rymodbus.net.target_addr); } else { vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno)); } } if (jsonRoot["targetPort"].isInt()) { - config_config.processes[pid].option.network.target_port = jsonRoot["targetPort"].asInt(); + config_config.processes[pid].option.rymodbus.net.target_port = jsonRoot["targetPort"].asInt(); } else if (jsonRoot["targetPort"].isString()) { - config_config.processes[pid].option.network.target_port = atoi(jsonRoot["targetPort"].asCString()); + config_config.processes[pid].option.rymodbus.net.target_port = atoi(jsonRoot["targetPort"].asCString()); } + //增加ftp协议参数 + if (jsonRoot["enableFtp"].isInt()) { + config_config.processes[pid].option.rymodbus.bHaveFTP = jsonRoot["enableFtp"].asInt(); + } else if (jsonRoot["enableFtp"].isString()) { + config_config.processes[pid].option.rymodbus.bHaveFTP = atoi(jsonRoot["enableFtp"].asCString()); + } else { //默认存在允许ftp功能 + config_config.processes[pid].option.rymodbus.bHaveFTP = TRUE; + } + //用户名 + if (jsonRoot["userName"].isString()) { + snprintf(config_config.processes[pid].option.rymodbus.ftp.user, sizeof(config_config.processes[pid].option.rymodbus.ftp.user), "%s", jsonRoot["userName"].asCString()); + } else { //默认存在允许ftp功能 + snprintf(config_config.processes[pid].option.rymodbus.ftp.user, sizeof(config_config.processes[pid].option.rymodbus.ftp.user), "%s", "administrator"); + } + //密码 + if (jsonRoot["passWord"].isString()) { + snprintf(config_config.processes[pid].option.rymodbus.ftp.password, sizeof(config_config.processes[pid].option.rymodbus.ftp.password), "%s", jsonRoot["passWord"].asCString()); + } else { //默认存在允许ftp功能 + snprintf(config_config.processes[pid].option.rymodbus.ftp.password, sizeof(config_config.processes[pid].option.rymodbus.ftp.password), "%s", "123456"); + } + //远程路径 + if (jsonRoot["remotePath"].isString()) { + snprintf(config_config.processes[pid].option.rymodbus.ftp.remotePath, sizeof(config_config.processes[pid].option.rymodbus.ftp.remotePath), "%s", jsonRoot["remotePath"].asCString()); + } else { //默认存在允许ftp功能 + snprintf(config_config.processes[pid].option.rymodbus.ftp.remotePath, sizeof(config_config.processes[pid].option.rymodbus.ftp.remotePath), "%s", "Hard Disk2/data/rtdatalog"); + } + + return TRUE; +} + +BOOLEAN CRYDevice::processRyFTP2MinioParam(const Json::Value jsonRoot, int pid) +{ + if (pid < 0 || pid >= PROCESSES_NUM) return FALSE; + + config_config.processes[pid].option.ftp2minio.net.ignored_source = TRUE; + config_config.processes[pid].option.ftp2minio.net.socket_type = SOCK_STREAM; + config_config.processes[pid].option.ftp2minio.net.bind_addr = INADDR_ANY; + config_config.processes[pid].option.ftp2minio.net.bind_port = 0; + config_config.processes[pid].option.ftp2minio.net.target_addr = INADDR_ANY; + config_config.processes[pid].option.ftp2minio.net.target_port = 502; + + if (jsonRoot["targetAddr"].isInt()) { + config_config.processes[pid].option.ftp2minio.net.target_addr = jsonRoot["targetAddr"].asInt(); + } else if (jsonRoot["targetAddr"].isString()) { + if (inet_pton(AF_INET, jsonRoot["targetAddr"].asCString(), &config_config.processes[pid].option.ftp2minio.net.target_addr) == 1) { + vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.ftp2minio.net.target_addr); + } else { + vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno)); + } + } + + //FTP参数 + //用户名 + if (jsonRoot["userName"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.user, sizeof(config_config.processes[pid].option.ftp2minio.ftp.user), "%s", jsonRoot["userName"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.user, sizeof(config_config.processes[pid].option.ftp2minio.ftp.user), "%s", "administrator"); + } + //密码 + if (jsonRoot["passWord"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.password, sizeof(config_config.processes[pid].option.ftp2minio.ftp.password), "%s", jsonRoot["passWord"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.password, sizeof(config_config.processes[pid].option.ftp2minio.ftp.password), "%s", "123456"); + } + //远程路径 + if (jsonRoot["remotePath"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.remotePath, sizeof(config_config.processes[pid].option.ftp2minio.ftp.remotePath), "%s", jsonRoot["remotePath"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.remotePath, sizeof(config_config.processes[pid].option.ftp2minio.ftp.remotePath), "%s", "Hard Disk2/data/rtdatalog"); + } + //本地路径 + if (jsonRoot["localPath"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.localPath, sizeof(config_config.processes[pid].option.ftp2minio.ftp.localPath), "%s", jsonRoot["localPath"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.ftp.localPath, sizeof(config_config.processes[pid].option.ftp2minio.ftp.localPath), "%s", "./"); + } + + //Minio参数 + //URL + if (jsonRoot["URL"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.minio.url, sizeof(config_config.processes[pid].option.ftp2minio.minio.url), "%s", jsonRoot["URL"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.minio.url, sizeof(config_config.processes[pid].option.ftp2minio.minio.url), "%s", "http://192.168.109.187:9000"); + } + //用户名 + if (jsonRoot["minioUserName"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.minio.user, sizeof(config_config.processes[pid].option.ftp2minio.minio.user), "%s", jsonRoot["minioUserName"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.minio.user, sizeof(config_config.processes[pid].option.ftp2minio.minio.user), "%s", "das"); + } + //密码 + if (jsonRoot["minioPassWord"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.minio.password, sizeof(config_config.processes[pid].option.ftp2minio.minio.password), "%s", jsonRoot["minioPassWord"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.minio.password, sizeof(config_config.processes[pid].option.ftp2minio.minio.password), "%s", "zaq12WSX"); + } + //桶 + if (jsonRoot["bucket"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.minio.bucket, sizeof(config_config.processes[pid].option.ftp2minio.minio.bucket), "%s", jsonRoot["bucket"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.minio.bucket, sizeof(config_config.processes[pid].option.ftp2minio.minio.bucket), "%s", "test"); + } + //桶中的绝对路径 + if (jsonRoot["object"].isString()) { + snprintf(config_config.processes[pid].option.ftp2minio.minio.object, sizeof(config_config.processes[pid].option.ftp2minio.minio.object), "%s", jsonRoot["object"].asCString()); + } else { + snprintf(config_config.processes[pid].option.ftp2minio.minio.object, sizeof(config_config.processes[pid].option.ftp2minio.minio.object), "%s", "/A-001/Alarm/"); + } return TRUE; } @@ -1153,15 +1292,37 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, } else { config_config.units[uid].yxs[point].m_param[0] = 0; } + //功能码 + if (jsonRoot["funcCode"].isString()) { + BYTE funcCode = (BYTE)atoi(jsonRoot["funcCode"].asCString()); + config_config.units[uid].yxs[point].m_param[0] = funcCode; + } else if (jsonRoot["funcCode"].isInt()) { + BYTE funcCode = (BYTE)jsonRoot["funcCode"].asInt(); + config_config.units[uid].yxs[point].m_param[0] = funcCode; + } else { + config_config.units[uid].yxs[point].m_param[0] = 0; + } + // if (jsonRoot["col2"].isString()) { BYTE offSet = (BYTE)atoi(jsonRoot["col2"].asCString()); config_config.units[uid].yxs[point].m_param[3] = offSet; - } if (jsonRoot["col2"].isInt()) { + } else if (jsonRoot["col2"].isInt()) { BYTE offSet = (BYTE)jsonRoot["col2"].asInt(); config_config.units[uid].yxs[point].m_param[3] = offSet; } else { config_config.units[uid].yxs[point].m_param[3] = 0; } + //偏移量 + if (jsonRoot["offSet"].isString()) { + BYTE offSet = (BYTE)atoi(jsonRoot["offSet"].asCString()); + config_config.units[uid].yxs[point].m_param[3] = offSet; + } else if (jsonRoot["offSet"].isInt()) { + BYTE offSet = (BYTE)jsonRoot["offSet"].asInt(); + config_config.units[uid].yxs[point].m_param[3] = offSet; + } else { + config_config.units[uid].yxs[point].m_param[3] = 0; + } + // if (jsonRoot["col3"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col3"].asCString()); config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff); @@ -1174,6 +1335,20 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yxs[point].m_param[1] = 0; config_config.units[uid].yxs[point].m_param[2] = 0; } + //寄存器 + if (jsonRoot["registerAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["registerAddr"].asCString()); + config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["registerAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["registerAddr"].asInt(); + config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else { + config_config.units[uid].yxs[point].m_param[1] = 0; + config_config.units[uid].yxs[point].m_param[2] = 0; + } + // break; case POINT_TYPE_YC: if (point >= config_config.units[uid].yccount) return FALSE; @@ -1186,6 +1361,17 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, } else { config_config.units[uid].ycs[point].m_param[0] = 0; } + //功能码 + if (jsonRoot["funcCode"].isString()) { + BYTE funcCode = (BYTE)atoi(jsonRoot["funcCode"].asCString()); + config_config.units[uid].ycs[point].m_param[0] = funcCode; + } else if (jsonRoot["funcCode"].isInt()) { + BYTE funcCode = jsonRoot["funcCode"].asInt(); + config_config.units[uid].ycs[point].m_param[0] = funcCode; + } else { + config_config.units[uid].ycs[point].m_param[0] = 0; + } + // if (jsonRoot["col2"].isString()) { BYTE dataType = (BYTE)atoi(jsonRoot["col2"].asCString()); config_config.units[uid].ycs[point].m_param[4] = dataType; @@ -1200,6 +1386,22 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].ycs[point].m_param[4] = 0; config_config.units[uid].ycs[point].m_param[3] = 1; } + //数据格式 + if (jsonRoot["dataType"].isString()) { + BYTE dataType = (BYTE)atoi(jsonRoot["dataType"].asCString()); + config_config.units[uid].ycs[point].m_param[4] = dataType; + if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1; + else config_config.units[uid].ycs[point].m_param[3] = 2; + } else if (jsonRoot["dataType"].isInt()) { + BYTE dataType = jsonRoot["dataType"].asInt(); + config_config.units[uid].ycs[point].m_param[4] = dataType; + if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1; + else config_config.units[uid].ycs[point].m_param[3] = 2; + } else { + config_config.units[uid].ycs[point].m_param[4] = 0; + config_config.units[uid].ycs[point].m_param[3] = 1; + } + // if (jsonRoot["col3"].isString()) { BYTE signMark = (BYTE)atoi(jsonRoot["col3"].asCString()); config_config.units[uid].ycs[point].m_param[5] = signMark; @@ -1209,6 +1411,17 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, } else { config_config.units[uid].ycs[point].m_param[5] = 0; } + //数据类型 + if (jsonRoot["signMark"].isString()) { + BYTE signMark = (BYTE)atoi(jsonRoot["signMark"].asCString()); + config_config.units[uid].ycs[point].m_param[5] = signMark; + } else if (jsonRoot["signMark"].isInt()) { + BYTE signMark = jsonRoot["signMark"].asInt(); + config_config.units[uid].ycs[point].m_param[5] = signMark; + } else { + config_config.units[uid].ycs[point].m_param[5] = 0; + } + // if (jsonRoot["col4"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff); @@ -1221,33 +1434,103 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].ycs[point].m_param[1] = 0; config_config.units[uid].ycs[point].m_param[2] = 0; } + //寄存器 + if (jsonRoot["registerAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["registerAddr"].asCString()); + config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["registerAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["registerAddr"].asInt(); + config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else { + config_config.units[uid].ycs[point].m_param[1] = 0; + config_config.units[uid].ycs[point].m_param[2] = 0; + } + // break; case POINT_TYPE_YM: if (point >= config_config.units[uid].ymcount) return FALSE; if (jsonRoot["col1"].isString()) { BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); config.units[uid].yms[point].m_param[0] = funcCode; + } else if (jsonRoot["col1"].isInt()) { + BYTE funcCode = jsonRoot["col1"].asInt(); + config_config.units[uid].yms[point].m_param[0] = funcCode; } else { config.units[uid].yms[point].m_param[0] = 0; } + //功能码 + if (jsonRoot["funcCode"].isString()) { + BYTE funcCode = (BYTE)atoi(jsonRoot["funcCode"].asCString()); + config.units[uid].yms[point].m_param[0] = funcCode; + } else if (jsonRoot["funcCode"].isInt()) { + BYTE funcCode = jsonRoot["funcCode"].asInt(); + config_config.units[uid].yms[point].m_param[0] = funcCode; + } else { + config.units[uid].yms[point].m_param[0] = 0; + } + // if (jsonRoot["col2"].isString()) { BYTE dataType = (BYTE)atoi(jsonRoot["col2"].asCString()); config.units[uid].yms[point].m_param[4] = dataType; if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1; if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4; else config.units[uid].yms[point].m_param[3] = 2; + } else if (jsonRoot["col2"].isInt()) { + BYTE dataType = jsonRoot["col2"].asInt(); + config.units[uid].yms[point].m_param[4] = dataType; + if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1; + if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4; + else config.units[uid].yms[point].m_param[3] = 2; } else { config.units[uid].yms[point].m_param[4] = 0; config.units[uid].yms[point].m_param[3] = 1; } + //数据格式 + if (jsonRoot["dataType"].isString()) { + BYTE dataType = (BYTE)atoi(jsonRoot["dataType"].asCString()); + config.units[uid].yms[point].m_param[4] = dataType; + if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1; + if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4; + else config.units[uid].yms[point].m_param[3] = 2; + } else if (jsonRoot["dataType"].isInt()) { + BYTE dataType = jsonRoot["dataType"].asInt(); + config.units[uid].yms[point].m_param[4] = dataType; + if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1; + if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4; + else config.units[uid].yms[point].m_param[3] = 2; + } else { + config.units[uid].yms[point].m_param[4] = 0; + config.units[uid].yms[point].m_param[3] = 1; + } + // if (jsonRoot["col4"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff); config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["col4"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["col4"].asInt(); + config_config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff); } else { config.units[uid].yms[point].m_param[1] = 0; config.units[uid].yms[point].m_param[2] = 0; } + //寄存器 + if (jsonRoot["registerAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["registerAddr"].asCString()); + config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff); + config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["registerAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["registerAddr"].asInt(); + config_config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff); + config_config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff); + } else { + config.units[uid].yms[point].m_param[1] = 0; + config.units[uid].yms[point].m_param[2] = 0; + } + // break; case POINT_TYPE_YK: if (point >= config_config.units[uid].ykcount) return FALSE; @@ -1264,17 +1547,28 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, if (jsonRoot["col1"].isString()) { BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString()); config_config.units[uid].yks[point].m_param[0] = funcCode; - } if (jsonRoot["col1"].isInt()) { + } else if (jsonRoot["col1"].isInt()) { BYTE funcCode = (BYTE)jsonRoot["col1"].asInt(); config_config.units[uid].yks[point].m_param[0] = funcCode; } else { config_config.units[uid].yks[point].m_param[0] = 0; } + //功能码 + if (jsonRoot["funcCode"].isString()) { + BYTE funcCode = (BYTE)atoi(jsonRoot["funcCode"].asCString()); + config_config.units[uid].yks[point].m_param[0] = funcCode; + } else if (jsonRoot["funcCode"].isInt()) { + BYTE funcCode = (BYTE)jsonRoot["funcCode"].asInt(); + config_config.units[uid].yks[point].m_param[0] = funcCode; + } else { + config_config.units[uid].yks[point].m_param[0] = 0; + } + // if (jsonRoot["col4"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString()); config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col4"].isInt()) { + } else if (jsonRoot["col4"].isInt()) { WORD registerAddr = (WORD)jsonRoot["col4"].asInt(); config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); @@ -1282,11 +1576,25 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yks[point].m_param[6] = 0xFF; config_config.units[uid].yks[point].m_param[7] = 0xFF; } + //合闸寄存器 + if (jsonRoot["closeRegisterAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["closeRegisterAddr"].asCString()); + config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); + config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["closeRegisterAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["closeRegisterAddr"].asInt(); + config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff); + config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff); + } else { + config_config.units[uid].yks[point].m_param[6] = 0xFF; + config_config.units[uid].yks[point].m_param[7] = 0xFF; + } + // if (jsonRoot["col6"].isString()) { WORD closeVal = (WORD)atoi(jsonRoot["col6"].asCString()); config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); - } if (jsonRoot["col6"].isInt()) { + } else if (jsonRoot["col6"].isInt()) { WORD closeVal = (WORD)jsonRoot["col6"].asInt(); config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); @@ -1294,11 +1602,25 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yks[point].m_param[10] = 0xFF; config_config.units[uid].yks[point].m_param[11] = 0xFF; } + //合闸值 + if (jsonRoot["closeValue"].isString()) { + WORD closeVal = (WORD)atoi(jsonRoot["closeValue"].asCString()); + config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); + config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); + } else if (jsonRoot["closeValue"].isInt()) { + WORD closeVal = (WORD)jsonRoot["closeValue"].asInt(); + config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff); + config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff); + } else { + config_config.units[uid].yks[point].m_param[10] = 0xFF; + config_config.units[uid].yks[point].m_param[11] = 0xFF; + } + // if (jsonRoot["col8"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col8"].asCString()); config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col8"].isInt()) { + } else if (jsonRoot["col8"].isInt()) { WORD registerAddr = (WORD)jsonRoot["col8"].asInt(); config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); @@ -1306,11 +1628,25 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yks[point].m_param[14] = 0xFF; config_config.units[uid].yks[point].m_param[15] = 0xFF; } + //分闸寄存器 + if (jsonRoot["openRegisterAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["openRegisterAddr"].asCString()); + config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); + config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); + } if (jsonRoot["openRegisterAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["openRegisterAddr"].asInt(); + config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff); + config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff); + } else { + config_config.units[uid].yks[point].m_param[14] = 0xFF; + config_config.units[uid].yks[point].m_param[15] = 0xFF; + } + // if (jsonRoot["col10"].isString()) { WORD openVal = (WORD)atoi(jsonRoot["col10"].asCString()); config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); - } if (jsonRoot["col10"].isInt()) { + } else if (jsonRoot["col10"].isInt()) { WORD openVal = (WORD)jsonRoot["col10"].asInt(); config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); @@ -1318,6 +1654,20 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yks[point].m_param[18] = 0xFF; config_config.units[uid].yks[point].m_param[19] = 0xFF; } + //分闸值 + if (jsonRoot["openValue"].isString()) { + WORD openVal = (WORD)atoi(jsonRoot["openValue"].asCString()); + config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); + config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); + } else if (jsonRoot["openValue"].isInt()) { + WORD openVal = (WORD)jsonRoot["openValue"].asInt(); + config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff); + config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff); + } else { + config_config.units[uid].yks[point].m_param[18] = 0xFF; + config_config.units[uid].yks[point].m_param[19] = 0xFF; + } + // break; case POINT_TYPE_YT: if (point >= config_config.units[uid].ytcount) return FALSE; @@ -1327,28 +1677,50 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yts[point].m_param[8] = 0xFF; config_config.units[uid].yts[point].m_param[9] = 0xFF; if (jsonRoot["col1"].isString()) { - BYTE nSetType = (BYTE)atoi(jsonRoot["col1"].asCString()); - config_config.units[uid].yts[point].m_param[0] = nSetType; - } if (jsonRoot["col1"].isInt()) { - BYTE nSetType = (BYTE)jsonRoot["col1"].asInt(); - config_config.units[uid].yts[point].m_param[0] = nSetType; + BYTE setType = (BYTE)atoi(jsonRoot["col1"].asCString()); + config_config.units[uid].yts[point].m_param[0] = setType; + } else if (jsonRoot["col1"].isInt()) { + BYTE setType = (BYTE)jsonRoot["col1"].asInt(); + config_config.units[uid].yts[point].m_param[0] = setType; } else { config_config.units[uid].yts[point].m_param[0] = 0; } + //设值方式 + if (jsonRoot["setType"].isString()) { + BYTE setType = (BYTE)atoi(jsonRoot["setType"].asCString()); + config_config.units[uid].yts[point].m_param[0] = setType; + } else if (jsonRoot["setType"].isInt()) { + BYTE setType = (BYTE)jsonRoot["setType"].asInt(); + config_config.units[uid].yts[point].m_param[0] = setType; + } else { + config_config.units[uid].yts[point].m_param[0] = 0; + } + // if (jsonRoot["col2"].isString()) { BYTE funcCode = (BYTE)atoi(jsonRoot["col2"].asCString()); config_config.units[uid].yts[point].m_param[1] = funcCode; - } if (jsonRoot["col2"].isInt()) { + } else if (jsonRoot["col2"].isInt()) { BYTE funcCode = (BYTE)jsonRoot["col2"].asInt(); config_config.units[uid].yts[point].m_param[1] = funcCode; } else { config_config.units[uid].yts[point].m_param[1] = 0; } + //功能码 + if (jsonRoot["funcCode"].isString()) { + BYTE funcCode = (BYTE)atoi(jsonRoot["funcCode"].asCString()); + config_config.units[uid].yts[point].m_param[1] = funcCode; + } else if (jsonRoot["funcCode"].isInt()) { + BYTE funcCode = (BYTE)jsonRoot["funcCode"].asInt(); + config_config.units[uid].yts[point].m_param[1] = funcCode; + } else { + config_config.units[uid].yts[point].m_param[1] = 0; + } + // if (jsonRoot["col5"].isString()) { WORD registerAddr = (WORD)atoi(jsonRoot["col5"].asCString()); config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); - } if (jsonRoot["col5"].isInt()) { + } else if (jsonRoot["col5"].isInt()) { WORD registerAddr = (WORD)jsonRoot["col5"].asInt(); config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); @@ -1356,6 +1728,20 @@ BOOLEAN CRYDevice::processModbusPointParam(const Json::Value jsonRoot, int uid, config_config.units[uid].yts[point].m_param[6] = 0xFF; config_config.units[uid].yts[point].m_param[7] = 0xFF; } + //寄存器地址 + if (jsonRoot["registerAddr"].isString()) { + WORD registerAddr = (WORD)atoi(jsonRoot["registerAddr"].asCString()); + config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); + config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); + } else if (jsonRoot["registerAddr"].isInt()) { + WORD registerAddr = (WORD)jsonRoot["registerAddr"].asInt(); + config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff); + config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff); + } else { + config_config.units[uid].yts[point].m_param[6] = 0xFF; + config_config.units[uid].yts[point].m_param[7] = 0xFF; + } + // break; default: break; } @@ -1431,7 +1817,10 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot) break; case PROTOCOL_HOST_MODBUS_TCP: case PROTOCOL_HOST_MODBUS_RTU_TCP: - processNetworkParam(params, i); + processRymodbustcpParam(params, i); + break; + case PROTOCOL_FTP2MINIO: + processRyFTP2MinioParam(params, i); break; case PROTOCOL_HOST_IEC104: processHostIEC104ProcessParam(params, i); @@ -1989,9 +2378,9 @@ bool CRYDevice::publishdeviceEventData(void) value["attrCode"] = (const char *)config.units[uid].yxs[yxbw_point].name; value["attrValue"] = yxbw_value; value["eventType"] = 0; - Json::Int64 datatime = (Json::Int64)time(NULL); - datatime *= 1000; - value["dataTime"] = datatime; + Json::Int64 eventTime = (Json::Int64)time(NULL); + eventTime *= 1000; + value["eventTime"] = eventTime; value["limitValue"] = Json::Value::null; root.append(value); @@ -2010,9 +2399,9 @@ bool CRYDevice::publishdeviceEventData(void) value["attrCode"] = (const char *)config.units[uid].ycs[ycbw_point].name; value["attrValue"] = ycbw_value; value["eventType"] = ycbw_type; - Json::Int64 datatime = (Json::Int64)time(NULL); - datatime *= 1000; - value["dataTime"] = datatime; + Json::Int64 eventTime = (Json::Int64)time(NULL); + eventTime *= 1000; + value["eventTime"] = eventTime; value["limitValue"] = GetUnitYCLimitReal(uid, ycbw_point, ycbw_type); root.append(value); diff --git a/das-dn/cmg/ry.h b/das-dn/cmg/ry.h index 3d851ebd..bc7f2cd8 100644 --- a/das-dn/cmg/ry.h +++ b/das-dn/cmg/ry.h @@ -42,6 +42,7 @@ typedef struct { typedef std::unordered_map name2servicemap; typedef std::unordered_map unitname2servicemap; +typedef std::unordered_map unitserviceName2cmdIdmap; typedef struct { std::string name; @@ -62,6 +63,7 @@ public: private: uid2pidmap uid2pid_map; unitname2servicemap unitname2service_map; + unitserviceName2cmdIdmap unitserviceName2cmdId_map; std::string m_traceId; LONG m_soeload = 0; @@ -92,8 +94,6 @@ private: time_t last_sec; private: - std::vector split(const std::string &s, char delimiter); - bool configInitializeMemory(void); bool configWriteSystemCFG(void); bool configWriteNodeCFG(void); @@ -120,18 +120,19 @@ private: int GetUnitYCBW(int& uid, LONG& value, int& type, unionCP56Time& st); BOOLEAN GetUnitYK(int uid, int& order, BYTE& value, BYTE& act, BYTE& result); void SetUnitYK(int uid, int order, BYTE value, BYTE act, BYTE result); - BOOLEAN GetUnitYT(int uid, int& order, DWORD& value, BYTE& act, BYTE& result); - void SetUnitYT(int uid, int order, DWORD value, BYTE act, BYTE result); - int MakeYKFrame(int uid); - int MakeYTFrame(int uid); - bool OnReceivedDeviceCommand(const Json::Value jsonRoot); - BOOLEAN processUartParam(const Json::Value jsonRoot, int ord); - BOOLEAN processNetworkParam(const Json::Value jsonRoot, int pid); - BOOLEAN processHostIEC104ProcessParam(const Json::Value jsonRoot, int pid); - BOOLEAN processModbusPointParam(const Json::Value jsonRoot, int uid, int point, int type); - bool dealConfigFile(const Json::Value jsonRoot); - bool OnReceivedSystemAction(const std::string cmdId, const std::string cmd, const Json::Value data); - void on_message(const char *msg, const int size); + BOOLEAN GetUnitYT(int, int& order, DWORD& value, BYTE& act, BYTE& result); + void SetUnitYT(int, int order, DWORD value, BYTE act, BYTE result); + int MakeYKFrame(int); + int MakeYTFrame(int); + bool OnReceivedDeviceCommand(const Json::Value); + BOOLEAN processUartParam(const Json::Value, int); + BOOLEAN processRymodbustcpParam(const Json::Value, int); + BOOLEAN processRyFTP2MinioParam(const Json::Value, int); + BOOLEAN processHostIEC104ProcessParam(const Json::Value, int pid); + BOOLEAN processModbusPointParam(const Json::Value, int, int, int); + bool dealConfigFile(const Json::Value); + bool OnReceivedSystemAction(const std::string, const std::string, const Json::Value); + void on_message(const char*, const int); void heart_beat(int status); bool publishinitDeviceData(int uid); diff --git a/das-dn/comm/public.cpp b/das-dn/comm/public.cpp index 90268937..81c3840d 100644 --- a/das-dn/comm/public.cpp +++ b/das-dn/comm/public.cpp @@ -322,6 +322,65 @@ DWORD BufToVal(BYTE* buf, int lenth, BOOLEAN bBigEndian) return sum; } +std::vector split(const std::string &s, char delimiter) +{ + std::vector tokens; + std::istringstream tokenStream(s); + std::string token; + while (std::getline(tokenStream, token, delimiter)) { + tokens.push_back(token); + } + return tokens; +} +// 计算新字符串的长度,考虑到每个指定字符都可能被替换为更长的转义序列 +size_t calculate_escaped_length(const char *str, char escape_char) +{ + size_t length = 0; + size_t i; + for (i = 0; str[i] != '\0'; i++) + { + if (str[i] == escape_char) + { + length += 3; // 每个指定字符替换为"\xXX"形式,长度为3 + } + else + { + length += 1; // 其他字符保持不变 + } + } + return length + 1; // 加1是为了字符串末尾的空字符 +} + +// 实现字符转义 +char* escape_char_in_string(const char *str, char escape_char) +{ + size_t new_length = calculate_escaped_length(str, escape_char); + + vLog(LOG_DEBUG, "new length is: %d\n", new_length); + char *escaped_str = (char *)malloc(new_length); + if (escaped_str == NULL) + { + return NULL; // 内存分配失败 + } + + size_t j = 0; + for (size_t i = 0; str[i] != '\0'; i++) + { + if (str[i] == escape_char) + { + sprintf(escaped_str + j, "%s", "\%20"); + j += 3; + } + else + { + escaped_str[j++] = str[i]; + } + } + escaped_str[j] = '\0'; // 添加字符串末尾的空字符 + + return escaped_str; +} + int unionCP56TimeToBuf(BYTE* buf, unionCP56Time st) { int len = 0; diff --git a/das-dn/hostmodbustcp/host_modbus_tcp.cpp b/das-dn/hostmodbustcp/host_modbus_tcp.cpp index cc4d42b0..d27d28d9 100644 --- a/das-dn/hostmodbustcp/host_modbus_tcp.cpp +++ b/das-dn/hostmodbustcp/host_modbus_tcp.cpp @@ -3,13 +3,12 @@ #include #include #include +#include -#ifdef HAVE_FTP_PROCESS - -#define MODBUSP_READ_ID 100 //读取文件及文件夹ID +#define MODBUSP_READ_ID 100 //读取文件及文件夹ID #define MODBUSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。 -#define MODBUSP_READ_ID_REGISTER_ADDRESS 150 //读取文件及文件夹ID寄存器地址。 -#define MODBUSP_READ_ID_REGISTER_LENGTH 9 //读取文件及文件夹ID寄存器长度。 +#define MODBUSP_READ_ID_REGISTER_ADDRESS 150 //读取文件及文件夹ID寄存器地址。 +#define MODBUSP_READ_ID_REGISTER_LENGTH 9 //读取文件及文件夹ID寄存器长度。 typedef std::unordered_map datalen2mbaddrmap; datalen2mbaddrmap m_datalen2mbaddr_map; @@ -189,8 +188,6 @@ struct { { 2, 368 } }; -#include - static int websocket_write(const noPollConn* conn, const char * buffer, int buffer_len) { int result; @@ -542,26 +539,38 @@ static void* ryftp_process(void* param) CHostModbusTcpProcess* mbt = (CHostModbusTcpProcess *)param; //获取此协议配置里面的ftp信息 - char remote[256]; - char name[256]; + 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* escaped_string = escape_char_in_string(mbt->m_remotePath, ' '); + if (escaped_string == NULL) + { + vLog(LOG_DEBUG, "路径转义错误!\n"); + 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 //配置的用户名和密码 -#if 0 snprintf(user, sizeof(user), "%s", mbt->m_user); snprintf(password, sizeof(password), "%s", mbt->m_password); -#endif + + //配置ip地址 DWORD target_addr = mbt->target_addr; memset(ipaddress, '\0', sizeof(ipaddress)); inet_ntop(AF_INET, &target_addr, ipaddress, 16); @@ -569,6 +578,7 @@ static void* ryftp_process(void* param) for (int i = 0; i < 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]; @@ -1055,7 +1065,6 @@ static void* ryftp_process(void* param) datatypeposmap yxdatamap; int yccount = GetUnitYCCount(uid); - vLog(LOG_DEBUG, "yccount is: %d.\n", yccount); for (int i = 0; i < yccount; i++) { //根据遥测参数配置寄存器,获取高频数据寄存器 WORD register_addr = GetUnitYCRegisterAddr(uid, i); @@ -1070,7 +1079,6 @@ static void* ryftp_process(void* param) } } int yxcount = GetUnitYXCount(uid); - vLog(LOG_DEBUG, "yxcount is: %d.\n", yxcount); for (int i = 0; i < yxcount; i++) { //根据遥测参数配置寄存器,获取高频数据寄存器 WORD register_addr = GetUnitYXRegisterAddr(uid, i); @@ -1087,6 +1095,7 @@ static void* ryftp_process(void* param) //根据实际配置表将 WORD ftpget_retry_count = 0; BOOLEAN bReadCurrentFile = TRUE; //读取当前文件标识 + while (TRUE) { sleep(1); //每秒执行一次 if (!mbt->m_bFtpRun) break; @@ -1099,16 +1108,17 @@ static void* ryftp_process(void* param) if (bReadCurrentFile) { //读取当前文件 snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_currentFileNo); - snprintf(remote, sizeof(remote), "ftp://%s/Hard%20Disk2/data/rtdatalog/%d/%d", ipaddress, mbt->m_currentDirNo, mbt->m_currentFileNo); + snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_currentDirNo, mbt->m_currentFileNo); } else { //读取未读的文件 snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_lastReadFileNo); - snprintf(remote, sizeof(remote), "ftp://%s/Hard%20Disk2/data/rtdatalog/%d/%d", ipaddress, mbt->m_lastReadDirNo, 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 int result = ftpget(remote, name, user, password, 3, &chunk); + if (result == CURLE_OK) { //成功,处理文件 vLog(LOG_DEBUG, "get %s to local %s, with name: %s, and password: %s okay.\n", remote, name, user, password); @@ -1221,9 +1231,6 @@ static void* ryftp_process(void* param) return ((void*)0); } -#endif - - CHostModbusTcpProcessItem::CHostModbusTcpProcessItem() { m_nNum = 0; @@ -1320,39 +1327,34 @@ CHostModbusTcpProcess::CHostModbusTcpProcess() m_nCurBeginReg = 0; m_nNeedSend = FALSE; -#ifdef HAVE_FTP_PROCESS //websocket接口 m_pid = 0; - //目录无效 m_iv = 1; - m_currentDirNo = -1; //当前目录编号 m_currentFileNo = -1; //当前文件编号 m_lastDirNo = -1; //上一目录编号 m_lastFileNo = -1; //上一文件编号 - m_bFtpRun = FALSE; -#endif } CHostModbusTcpProcess::~CHostModbusTcpProcess() { - vLog(LOG_DEBUG, "here.....\n"); -#ifdef HAVE_FTP_PROCESS - m_bFtpRun = FALSE; - vLog(LOG_DEBUG, "保存本协议读取到的那个目录和文件\n"); - char fileName[260]; - snprintf(fileName, sizeof(fileName), "hostmodbustcp_%d.mem", GetCurID()); - FILE *pf = fopen(fileName, "w+"); - if (pf) + if (m_bHaveFTP) { - fwrite(&m_currentDirNo, sizeof(LONG), 1, pf); - fwrite(&m_currentFileNo, sizeof(LONG), 1, pf); - fwrite(&m_currentDirStartFileNo, sizeof(LONG), 1, pf); - fclose(pf); + m_bFtpRun = FALSE; + vLog(LOG_DEBUG, "保存本协议读取到的那个目录和文件\n"); + char fileName[260]; + snprintf(fileName, sizeof(fileName), "hostmodbustcp_%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); + } } -#endif } CNetProcessItem *CHostModbusTcpProcess::CreateItem(int ord) @@ -1668,50 +1670,62 @@ BOOLEAN CHostModbusTcpProcess::OnPreCreate(int id) { if (!CNetProcess::OnPreCreate(id)) return FALSE; + if (!GetOption(&m_nOptions, sizeof(m_nOptions))) + { + vLog(LOG_DEBUG, "润阳modbus读取配置错误。"); + return FALSE; + } + + m_bHaveFTP = m_nOptions.bHaveFTP; m_nTimeout = 200; calc2(); -#ifdef HAVE_FTP_PROCESS - vLog(LOG_DEBUG, "file size is: %d\n", sizeof(struRYDeviceData) * 250 / 1024); - //读取文件 - m_lastReadDirNo = 1; - m_lastReadFileNo = 1; - m_lastReadDirStartFileNo = 1; - m_bHaveUnReadFile = TRUE; - - char fileName[260]; - snprintf(fileName, sizeof(fileName), "hostmodbustcp_%d.mem", GetCurID()); - FILE *pf = fopen(fileName, "rb"); - if (pf) + if (m_bHaveFTP) { - 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, "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); + 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); - if (pthread_create(&m_pid, &attr, ryftp_process, this) < 0) { - vLog(LOG_ERROR, "create ryftp_process error(%d,%s).\n", errno, strerror(errno)); - return TRUE; + vLog(LOG_DEBUG, "file size is: %d\n", sizeof(struRYDeviceData) * 250 / 1024); + //读取文件 + m_lastReadDirNo = 1; + m_lastReadFileNo = 1; + m_lastReadDirStartFileNo = 1; + m_bHaveUnReadFile = TRUE; + + char fileName[260]; + snprintf(fileName, sizeof(fileName), "hostmodbustcp_%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); } - char name[17]; - snprintf(name, 16, "%s_ftp", GetCurProcessName()); - pthread_setname_np(m_pid, name); - pthread_attr_destroy(&attr); - } + //启动后,创建ftp线程 + if (m_pid <= 0) { + m_bFtpRun = TRUE; + vLog(LOG_DEBUG, "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); -#endif + if (pthread_create(&m_pid, &attr, ryftp_process, this) < 0) { + vLog(LOG_ERROR, "create ryftp_process error(%d,%s).\n", errno, strerror(errno)); + return TRUE; + } + char name[17]; + snprintf(name, 16, "%s_ftp", GetCurProcessName()); + pthread_setname_np(m_pid, name); + + pthread_attr_destroy(&attr); + } + } return TRUE; } @@ -1816,18 +1830,18 @@ BOOLEAN CHostModbusTcpProcess::OnTimer(void) if (pItem == NULL) return TRUE; m_nNeedSend = TRUE; -#ifdef HAVE_FTP_PROCESS - //启动时读取一次,后面自己维护序号 - if ((m_currentDirNo == -1) && (m_currentFileNo == -1)) - { //当前文件和目录都为-1,程序第一次启动。需要获取ftp目录及文件ID - m_nFrameType = MODBUSP_READ_ID; - m_nCurFuncCode = MODBUSP_READ_ID_FUNCCODE; - m_nCurBeginReg = MODBUSP_READ_ID_REGISTER_ADDRESS; - m_nCurRegCount = MODBUSP_READ_ID_REGISTER_LENGTH; - pItem->m_nFramePoll |= MODBUSP_GET_DATA_FRAME; - return TRUE; + if (m_bHaveFTP) + { //启动时读取一次,后面自己维护序号 + if ((m_currentDirNo == -1) && (m_currentFileNo == -1)) + { //当前文件和目录都为-1,程序第一次启动。需要获取ftp目录及文件ID + m_nFrameType = MODBUSP_READ_ID; + m_nCurFuncCode = MODBUSP_READ_ID_FUNCCODE; + m_nCurBeginReg = MODBUSP_READ_ID_REGISTER_ADDRESS; + m_nCurRegCount = MODBUSP_READ_ID_REGISTER_LENGTH; + pItem->m_nFramePoll |= MODBUSP_GET_DATA_FRAME; + return TRUE; + } } -#endif struModbusExtFrame* frame = pItem->GetNextFrame(); if (frame != NULL) { @@ -2237,12 +2251,10 @@ BOOLEAN CHostModbusTcpProcess::OnReceiveData(CHostModbusTcpProcessItem *pItem, B { return OnReceiveYMData(pItem, &pData[3], count); } -#ifdef HAVE_FTP_PROCESS else if (m_nCurFrame == MODBUSP_READ_ID) { return OnReceiveIDData(pItem, &pData[3], count); } -#endif else if (m_nCurFrame == MODBUSP_YK_EXECUTE) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_EXEED, YKR_SUCC); @@ -2284,7 +2296,6 @@ BOOLEAN CHostModbusTcpProcess::OnReceiveData(CHostModbusTcpProcessItem *pItem, B return FALSE; } -#ifdef HAVE_FTP_PROCESS BOOLEAN CHostModbusTcpProcess::OnReceiveIDData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int uid; @@ -2339,7 +2350,6 @@ BOOLEAN CHostModbusTcpProcess::OnReceiveIDData(CHostModbusTcpProcessItem *pItem, return TRUE; } -#endif BOOLEAN CHostModbusTcpProcess::OnReceiveYXData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { diff --git a/das-dn/hostmodbustcp/host_modbus_tcp.h b/das-dn/hostmodbustcp/host_modbus_tcp.h index e8b38634..622abedc 100644 --- a/das-dn/hostmodbustcp/host_modbus_tcp.h +++ b/das-dn/hostmodbustcp/host_modbus_tcp.h @@ -4,8 +4,6 @@ #include "netproc.h" #include "modbus_def.h" -//#define HAVE_FTP_PROCESS -#ifdef HAVE_FTP_PROCESS #include #include #include @@ -172,8 +170,6 @@ typedef struct { } struRYDeviceData; #pragma pack() -#endif - class CHostModbusTcpProcessItem : public CNetProcessItem { public: @@ -222,12 +218,21 @@ private: void sort1(STRUCT_PARAM*, int); //功能码排序 void sort2(STRUCT_PARAM*, int); //寄存地址排序 -#ifdef HAVE_FTP_PROCESS + struRYModbusOption m_nOptions; //增加websocket连接 pthread_t m_pid; short m_uid; public: + BOOLEAN m_bHaveFTP; //存在FTP协议 + + //ftp参数信息 + char m_user[64]; + char m_password[64]; + char m_remotePath[128]; + char m_localPath[128]; + + //文件信息 int m_iv; LONG m_currentDirNo; //当前目录编号 LONG m_currentFileNo; //当前文件编号 @@ -243,10 +248,6 @@ public: BOOLEAN m_bHaveUnReadFile; //存在未读的文件 BOOLEAN m_bFtpRun; - //ftp参数信息 - char m_user[128]; - char m_password[128]; - char m_remoteIp[64]; int _mkdir(const char* pathName) { if (access(pathName, F_OK) == 0) return 0; @@ -258,8 +259,6 @@ public: return 1; } -#endif - public: CHostModbusTcpProcess(); virtual ~CHostModbusTcpProcess(); @@ -279,9 +278,9 @@ public: BOOLEAN OnReceiveData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count); int OnPackageReceived(BYTE* pBuf, int count, int ord /* = -1 */); -#ifdef HAVE_FTP_PROCESS + virtual BOOLEAN OnReceiveIDData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count); -#endif + virtual BOOLEAN OnReceiveYXData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count); virtual BOOLEAN OnReceiveYCData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count); virtual BOOLEAN OnReceiveYMData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count); diff --git a/das-dn/inc/public.h b/das-dn/inc/public.h index 16f8a081..1e0b7bdd 100644 --- a/das-dn/inc/public.h +++ b/das-dn/inc/public.h @@ -198,7 +198,7 @@ typedef int SOCKET; #define PROTOCOL_SUB_GDW104 47 //国网104从 #define PROTOCOL_HW_MQTT 72 //华为物联平台ROMA #define PROTOCOL_OPCUA 78 //opcua协议 - +#define PROTOCOL_FTP2MINIO 79 //opcua协议 #define ADDR_TYPE_NORMAL 0 #define ADDR_TYPE_HEX 1 @@ -602,6 +602,38 @@ typedef struct } struNetWorkOption; //end +// add by assouan for ry modbus options, it has ftp paramters; +typedef struct +{ + char user[64]; + char password[64]; + char remotePath[128]; + char localPath[128]; +} struFTPOption; + +typedef struct +{ + char url[256]; + char user[64]; + char password[64]; + char bucket[64]; + char object[256]; +} struMINIOOption; + +typedef struct +{ + struNetWorkOption net; + BOOLEAN bHaveFTP; + struFTPOption ftp; +} struRYModbusOption; + +typedef struct +{ + struNetWorkOption net; + struFTPOption ftp; + struMINIOOption minio; +} struRYFTP2MINIOOption; + typedef struct { BOOLEAN use_owner_config; //单元配置是否启用 @@ -824,6 +856,8 @@ typedef union struIEC104Option iec104; struIEC103Option iec103; struIEC101Option iec101; + struRYModbusOption rymodbus; + struRYFTP2MINIOOption ftp2minio; } unionProcOption; typedef struct @@ -1346,6 +1380,8 @@ time_t unionCP56TimetoTime_t(unionCP56Time* st); unionCP56Time Time_ttounionCP56Time(time_t st); QLONG filetime_to_unix(QLONG ft); QWORD getTimeInMs(); +char* escape_char_in_string(const char *str, char escape_char); +std::vector split(const std::string &s, char delimiter); ////////////////////////////////////////////////////////////////////////// typedef enum { diff --git a/das-dn/minio/ftp2minio.cpp b/das-dn/minio/ftp2minio.cpp new file mode 100644 index 00000000..b4ae9e1e --- /dev/null +++ b/das-dn/minio/ftp2minio.cpp @@ -0,0 +1,375 @@ +#include "ftp2minio.h" +#include +#include + +FtpManage::FtpManage(const std::string user, const std::string password, const std::string id) + :Ftp_ip(id), User(user), Password(password) +{ + CURLcode res = curl_global_init(CURL_GLOBAL_ALL); // 初始化全局环境只需要初始化一次 + if (res != CURLE_OK) + { + vLog(LOG_ERROR, "curl_global_init() falied %s\n", curl_easy_strerror(res)); + return; + } +} + +FtpManage::~FtpManage() +{ + if (curl) + { + curl_easy_cleanup(curl); + } + curl_global_cleanup(); +} + +//接收消息回调函数 +size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) +{ + size_t totalSize = size * nmemb; + output->append(static_cast(contents), totalSize); + return totalSize; +} + +// 初始化curl +void FtpManage::SetURL() +{ + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); // 设置长连接 + curl_easy_setopt(curl, CURLOPT_USERPWD, (User + ':' + Password).c_str()); //设置用户名和密码 +} + +// 把带有路径的文件转换为文件名 D:/ggbond/123.jpg->123.jpg +std::string FtpManage::GetFileNameFromPath(const std::string& filePath) +{ + if (filePath == "") return filePath; + + //去除路径最后的空格 + std::string retPath; + size_t lastBlank = filePath.find_last_not_of(' '); + if (lastBlank != std::string::npos) + { + retPath = filePath.substr(0, lastBlank+1); + } + else + { + return ""; + } + size_t lastSlashPos = retPath.find_last_of("/\\"); + if (lastSlashPos != std::string::npos) + { + return retPath.substr(lastSlashPos + 1); + } + else + { // 如果没有找到斜杠或反斜杠,整个路径就是文件名 + return retPath; + } +} +// 下载单一文件,把remoteFilePath的文件下载到localDirectory里面 +bool FtpManage::DownloadFile(const char* remoteFilePath, const char* localDirectory) +{ + SetURL(); + _URL = Ftp_ip + remoteFilePath; + curl_easy_setopt(curl, CURLOPT_URL, _URL.c_str()); // 设置请求的URL + if (curl) + { + FILE* fp = fopen((localDirectory + GetFileNameFromPath(remoteFilePath)).c_str(), "wb"); + if (fp) + { // 设置文件写入地址 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + // 执行任务 + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) + { + vLog(LOG_ERROR, "DownLoad file: %s failed<%s>.", remoteFilePath, curl_easy_strerror(res)); + fclose(fp); + curl_easy_cleanup(curl); + return false; + } + else + { + vLog(LOG_DEBUG, "DownLoad file: %s successfully!\n", remoteFilePath); + fclose(fp); + } + } + else + { + vLog(LOG_ERROR, "file open failed!\n"); + curl_easy_cleanup(curl); // 清除curl + return false; + } + } + curl_easy_cleanup(curl); + return true; +} +// 下载全部文件 +bool FtpManage::DownloadAllFiles(const char* remoteFilePath, const char* localDirectory) +{ + if (GetfilenameFromftp(remoteFilePath)) + { + for (const auto& fns : fNs) + { + std::string filename = remoteFilePath + fns; + bool res = DownloadFile(filename.c_str(), localDirectory); + if (res) continue; + else + { + return false; + } + } + } + return true; +} + +// 获取ftp某个文件夹内文件名 +bool FtpManage::GetfilenameFromftp(const std::string filePath) +{ + SetURL(); + std::string path = Ftp_ip + filePath; + std::string fileName; // 文件名列表保存位置 + + vLog(LOG_DEBUG, "path is: %s", path.c_str()); + if (curl) + { + curl_easy_setopt(curl, CURLOPT_URL, path.c_str()); // 设置访问URL + curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); // 设置只返回文件 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileName); // 设置只获取文件名列表 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); // 设置get的回调函数 + if (curl_easy_perform(curl) == CURLE_OK) //执行任务 + { + fNs.clear(); + size_t startPos = 0, endPos = 0; + while ((endPos = fileName.find('\n', startPos)) != std::string::npos ) + { + std::string name = fileName.substr(startPos, endPos - startPos); + fNs.emplace_back(name); + startPos = endPos + 1; + } + } + } + else + { + return false; + } + curl_easy_cleanup(curl); + return true; +} + +// 获取FTP文件夹内所有文件名的接口函数 +const std::vector& FtpManage::GetFilesName(const std::string filepath) +{ + if (GetfilenameFromftp(filepath)) + { + return fNs; + } + return std::vector(); +} + +CFtp2MinioProcess::CFtp2MinioProcess() +{ + m_pAftp = NULL; +} + +CFtp2MinioProcess::~CFtp2MinioProcess() +{ + if (m_pAftp) delete m_pAftp; + m_pAftp = NULL; + saveMapToFile(); +} + +void CFtp2MinioProcess::saveMapToFile(void) +{ + char fileName[260]; + snprintf(fileName, sizeof(fileName), "minioftp_%d.mem", GetCurID()); + std::ofstream outFile(fileName); + if (!outFile) + { + vLog(LOG_ERROR, "Unable to open file for writing!\n"); + return; + } + for (const auto& pair : fileName2Id_map) + { + outFile << pair.first << " " << pair.second << std::endl; + } + outFile.close(); +} + +void CFtp2MinioProcess::loadMapFromFile(void) +{ + char fileName[260]; + snprintf(fileName, sizeof(fileName), "minioftp_%d.mem", GetCurID()); + std::ifstream inFile(fileName); + if (!inFile) + { + vLog(LOG_ERROR, "Unable to open file for reading!\n"); + return; + } + std::string key; + int value; + fileName2Id_map.clear(); + while (inFile >> key >> value) { + fileName2Id_map[key] = value; //如果键已经存在,则会更新其值 + } + inFile.close(); +} + +BOOLEAN CFtp2MinioProcess::OnPreCreate(int id) +{ + if (!CProcess::OnPreCreate(id)) return FALSE; + + DWORD target_addr; + if (!GetOption(&m_nOptions, sizeof(m_nOptions))) + { //获取新配置 + vLog(LOG_DEBUG, "润阳ftp转modbus读取配置错误。"); + return FALSE; + } + + if (m_pAftp) m_pAftp = NULL; + + target_addr = m_nOptions.net.target_addr; + + char user[128] = "administrator"; + char password[128] = "123456"; + char ipaddress[128] = "127.0.0.1"; + char remotePath[128] = "\0"; + char localPath[128]; + char url[256]; + char listpath[256]; + snprintf(user, sizeof(user), "%s", m_nOptions.ftp.user); + snprintf(password, sizeof(password), "%s", m_nOptions.ftp.password); + snprintf(localPath, sizeof(localPath), "%s", m_nOptions.ftp.localPath); + m_localPath = std::string(localPath); + + char *escaped_string = escape_char_in_string(m_nOptions.ftp.remotePath, ' '); + if (!escaped_string) return FALSE; + snprintf(remotePath, sizeof(remotePath), "%s", escaped_string); + free(escaped_string); + + memset(ipaddress, '\0', sizeof(ipaddress)); + inet_ntop(AF_INET, &target_addr, ipaddress, 16); + + snprintf(url, sizeof(url), "ftp://%s", ipaddress); + snprintf(listpath, sizeof(listpath), "/%s", remotePath); + + m_pAftp = new FtpManage(user, password, url); + m_listPath = std::string(listpath); + + fileName2Id_map.clear(); + //读取列表 + loadMapFromFile(); + + last_count = fileName2Id_map.size(); + return TRUE; +} + +BOOLEAN CFtp2MinioProcess::Run(void) +{ + if (!CProcess::Run()) return FALSE; + + return TRUE; +} + +BOOLEAN CFtp2MinioProcess::OnTimer(void) +{ + if (!CProcess::OnTimer()) return FALSE; + + BOOLEAN min_changed = FALSE; + if (last_min != system32.now.minute) + { + last_min = system32.now.minute; + min_changed = TRUE; + } + if (min_changed) + { + vLog(LOG_DEBUG, "准备读取文件夹%s的内容\n", m_listPath.c_str()); + for (const auto& n : m_pAftp->GetFilesName(m_listPath)) + { + std::string remotefile = m_listPath + "/" + n; + std::string localpath = m_localPath; + if (fileName2Id_map.find(n) == fileName2Id_map.end()) + { + fileName2Id_map.insert(fileName2Idmap::value_type(n, 0)); + if (m_pAftp->DownloadFile(remotefile.c_str(), localpath.c_str())) + { + vLog(LOG_DEBUG, "下载成功!\n"); + push2minio(n); + } + } + else + { + vLog(LOG_WARN, "该文件:%s已经被下载。\n", n.c_str()); + return TRUE; + } + } + if (last_count != fileName2Id_map.size()) + { + last_count = fileName2Id_map.size(); + saveMapToFile(); + } + } + return TRUE; +} + +BOOLEAN CFtp2MinioProcess::push2minio(std::string pathName) +{ + //创建URL + //minio::s3::BaseUrl base_url("http://192.168.109.187:9000"); + minio::s3::BaseUrl base_url(m_nOptions.minio.url); + base_url.https = false; + + //创建鉴权对象 + //minio::creds::StaticProvider provider("das", "zaq12WSX"); + minio::creds::StaticProvider provider(m_nOptions.minio.user, m_nOptions.minio.password); + + // 创建客户端 + minio::s3::Client client(base_url, &provider); + //std::string bucket_name = "test"; + std::string bucket_name = std::string(m_nOptions.minio.bucket); + + // 检查test桶是否存在 + bool exist; + { + minio::s3::BucketExistsArgs args; + args.bucket = bucket_name; + + minio::s3::BucketExistsResponse resp = client.BucketExists(args); + if (!resp) { + vLog(LOG_ERROR, "unable to do bucket existence check; %s\n", resp.Error()); + return FALSE; + } + + exist = resp.exist; + } + + // 如果test桶不存在,则创建test桶 + if (!exist) { + minio::s3::MakeBucketArgs args; + args.bucket = bucket_name; + + minio::s3::MakeBucketResponse resp = client.MakeBucket(args); + if (!resp) { + vLog(LOG_ERROR, "unable to create bucket; %s\n", resp.Error()); + return FALSE; + } + } + + // 上传文件 + minio::s3::UploadObjectArgs args; + args.bucket = bucket_name; + //上传到桶中的绝对路径 + //char *pYMDhms = strchr((char *)pathName.c_str(), '.'); + //args.object = "/A-001/Alarm/" + pathName; + args.object = std::string(m_nOptions.minio.object) + pathName; + + //本地文件系统中的绝对路径 + args.filename = pathName;//"/das/minio-example/test.txt"; + + minio::s3::UploadObjectResponse resp = client.UploadObject(args); + if (!resp) { + vLog(LOG_ERROR, "unable to upload object; %s\n", resp.Error()); + return FALSE; + } + + vLog(LOG_DEBUG, "'%s' is successfully uploaded as object '%s' to bucket 'test'.", args.filename.c_str(), args.object.c_str()); + + return TRUE; +} diff --git a/das-dn/minio/ftp2minio.h b/das-dn/minio/ftp2minio.h new file mode 100644 index 00000000..c747ca62 --- /dev/null +++ b/das-dn/minio/ftp2minio.h @@ -0,0 +1,65 @@ +#ifndef _ZJD_FTP2MINIO_PROCESS_H_ +#define _ZJD_FTP2MINIO_PROCESS_H_ + +#include "process.h" +#include +#include +#include +#include +#include + +class FtpManage +{ +public: + FtpManage(); + FtpManage(const std::string user, const std::string password, const std::string id); + ~FtpManage(); + + bool DownloadFile(const char* remoteFilePath, const char* localDirectory); + bool DownloadAllFiles(const char* remoteFilePath, const char* localDirectory); + const std::vector& GetFilesName(const std::string filepath); + +private: + void SetURL(); + std::string UrlEncode(const std::string& value); + std::string GetFileNameFromPath(const std::string& filePath); + bool GetfilenameFromftp(const std::string directoryname); + +private: + std::string Ftp_ip; //Ftp服务器地址 + std::string User, Password; //登录用户名及密码 + std::string _URL; + std::vector fNs; //用于记录全部文件名 + CURL* curl; +}; + +typedef std::unordered_map fileName2Idmap; + +class CFtp2MinioProcess : public CProcess +{ +public: + CFtp2MinioProcess(); + virtual ~CFtp2MinioProcess(); + + virtual BOOLEAN OnPreCreate(int id); + virtual BOOLEAN Run(void); + virtual BOOLEAN OnTimer(void); + +private: + FtpManage* m_pAftp; + std::string m_listPath; //需要查询的目录 + std::string m_localPath; //文件保存到本地的目录 + + //struNetWorkOption network; + struRYFTP2MINIOOption m_nOptions; + + DWORD last_min; + fileName2Idmap fileName2Id_map; + DWORD last_count; + void saveMapToFile(void); + void loadMapFromFile(void); + + BOOLEAN push2minio(std::string); +}; + +#endif //_ZJD_FTP2MINIO_PROCESS_H_