diff --git a/.vscode/settings.json b/.vscode/settings.json index d48bfef1..6d66d6d9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,61 @@ "xloctime": "cpp", "xhash": "cpp", "string": "cpp", - "sstream": "cpp" + "sstream": "cpp", + "xutility": "cpp", + "array": "cpp", + "ranges": "cpp", + "span": "cpp", + "vector": "cpp", + "system_error": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "format": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "map": "cpp", + "memory": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "set": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xmemory": "cpp", + "xtr1common": "cpp", + "xtree": "cpp" } } \ No newline at end of file diff --git a/das-dn/CMakeLists.txt b/das-dn/CMakeLists.txt index 45239f79..def20bc0 100644 --- a/das-dn/CMakeLists.txt +++ b/das-dn/CMakeLists.txt @@ -220,5 +220,6 @@ if (UNIX) #set (APP_LIBS ${APP_LIBS} websockets) endif() +#add_link_options (-static) add_executable (application ${APP_SRCS}) target_link_libraries (application ${APP_LIBS}) diff --git a/das-dn/cmg/changemaster.cpp b/das-dn/cmg/changemaster.cpp index 8d607cc3..6f67b7d5 100644 --- a/das-dn/cmg/changemaster.cpp +++ b/das-dn/cmg/changemaster.cpp @@ -48,8 +48,6 @@ CChangeMaster::CChangeMaster() memset(m_control.m_hostTr, 0, HOST_NAME_LENGTH); m_control.m_total = TCI_CHANGE_FULL_CRITICAL; uart_fd = -1; - - m_conn = NULL; } CChangeMaster::~CChangeMaster() @@ -114,7 +112,7 @@ BOOLEAN CChangeMaster::uart_init(const char *dev) return TRUE; } -BOOLEAN CChangeMaster::Init(noPollConn *conn) +BOOLEAN CChangeMaster::Init(void) { if (nodes.interfaces.enable) { @@ -123,10 +121,6 @@ BOOLEAN CChangeMaster::Init(noPollConn *conn) return uart_init(uart_dev); } - if (conn) - { - m_conn = conn; - } return TRUE; } @@ -348,7 +342,7 @@ void CChangeMaster::StartUp(void) else if (PROTOCOL_HOST_MODBUS_TCP == config.processes[i].proto) { vLog(LOG_INFO, "协议<%d>创建为: modbus tcp主协议.\n", i); - procs[i] = new CHostModbusTcpProcess(m_conn); + procs[i] = new CHostModbusTcpProcess(); } else if (PROTOCOL_HOST_IEC104 == config.processes[i].proto) { diff --git a/das-dn/cmg/changemaster.h b/das-dn/cmg/changemaster.h index fff7094d..b8d0a2a3 100644 --- a/das-dn/cmg/changemaster.h +++ b/das-dn/cmg/changemaster.h @@ -5,9 +5,6 @@ #include #include -#include -#include - #define MASTER_TCI_ALIVE 0x55 #define MASTER_TCI_SEND_INTERVAL (1000*200) //sleep(1) #define TCI_CHANGE_FULL_CRITICAL 5 @@ -51,7 +48,7 @@ public: ChangeMaster m_changeStruct; ChangeControl m_control; public: - BOOLEAN Init(noPollConn *conn); + BOOLEAN Init(void); void OnReceive(ChangeMaster chControl); protected: @@ -74,8 +71,6 @@ private: BOOLEAN IsMasterTci(); void StartUp(void); - - noPollConn *m_conn; }; void *ChangeNewObject(void *args); diff --git a/das-dn/cmg/main.cpp b/das-dn/cmg/main.cpp index aedc9a96..b58aab49 100644 --- a/das-dn/cmg/main.cpp +++ b/das-dn/cmg/main.cpp @@ -2127,7 +2127,7 @@ int main(int argc, char** argv) char host[256] = {"127.0.0.1"}; int port = 7790; char nodeId[128] = {"runyang_dn"}; - char version[128] = {"v1.0"}; + char version[128] = {"0"}; //获取可执行文件所在目录 const char default_config[] = "[global]\n" @@ -2215,7 +2215,6 @@ int main(int argc, char** argv) noPollConn *conn; DWORD last_connect_sec = 0; #else - noPollConn *conn = NULL; CRYDevice ryDevice; #endif @@ -2243,7 +2242,6 @@ int main(int argc, char** argv) } } else { if (enable_auto_platform) { //增加协议和单元配置的数量统计 -#ifdef MAIN_FILE vLog(LOG_DEBUG, "configed node id is: %s.\n", nodes.m_node[0].m_machine_name); snprintf(nodeId, sizeof(nodeId), "%s", nodes.m_node[0].m_machine_name); if (system32.version[0] != '\0') { @@ -2251,6 +2249,7 @@ 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; @@ -2308,7 +2307,7 @@ int main(int argc, char** argv) //last_connect_sec = system32.timers; } #else - conn = ryDevice.ry_init(host, port, nodeId, version); + ryDevice.ry_init(host, port, nodeId, version); #endif } @@ -2317,7 +2316,7 @@ int main(int argc, char** argv) unsigned int critical = 0; CChangeMaster masterTci; - if (!masterTci.Init(conn)) { + if (!masterTci.Init()) { break; } diff --git a/das-dn/cmg/ry.cpp b/das-dn/cmg/ry.cpp index 3fcb3142..852a454b 100644 --- a/das-dn/cmg/ry.cpp +++ b/das-dn/cmg/ry.cpp @@ -297,7 +297,7 @@ bool CRYDevice::publish_sensor_data(noPollConn* conn, const std::string traceId, jsonRoot["cmd"] = command; char str[128]; - snprintf(str, sizeof(str), "%lld", snowflake_next_id(&m_sf)); + snprintf(str, sizeof(str), "%lld", snowflake_next_id()); if (traceId == "") { jsonRoot["cmdId"] = str; @@ -311,7 +311,7 @@ bool CRYDevice::publish_sensor_data(noPollConn* conn, const std::string traceId, 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()); + vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n", command, outputConfig.length()); 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); @@ -1450,7 +1450,9 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot) if (attr["type"].isString()) type = attr["type"].asString(); struct_attr name_param; name_param.name = ""; + name_param.highSpeed = 0; if (attr["name"].isString()) name_param.name = attr["name"].asString(); + if (attr["highSpeed"].isInt()) name_param.highSpeed = attr["highSpeed"].asInt(); 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); @@ -1504,10 +1506,12 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot) 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; + config_config.units[uid].ycs[k].highSpeed = ycs[k].highSpeed; 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["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(); @@ -1826,6 +1830,9 @@ bool CRYDevice::publishAnalogData(noPollConn* conn, int uid) } } if (values.size()) { + Json::Int64 datatime = (Json::Int64)time(NULL); + datatime *= 1000; + root["dataTime"] = datatime; root["deviceId"] = static_units[uid].deviceId; root["values"] = values; return publish_sensor_data(conn, "", "analogData", root); @@ -1845,6 +1852,9 @@ bool CRYDevice::publishStateData(noPollConn* conn, int uid) } } if (values.size()) { + Json::Int64 datatime = (Json::Int64)time(NULL); + datatime *= 1000; + root["dataTime"] = datatime; root["deviceId"] = static_units[uid].deviceId; root["values"] = values; return publish_sensor_data(conn, "", "stateData", root); @@ -1886,7 +1896,7 @@ void CRYDevice::releaseAllUnits(void) } } -noPollConn *CRYDevice::ry_init(const char *host, const int port, const char *nodeId, const char *version) +BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId, const char *version) { snprintf(m_host, sizeof(m_host), "%s", host); snprintf(m_nodeId, sizeof(m_nodeId), "%s", nodeId); @@ -1948,10 +1958,10 @@ noPollConn *CRYDevice::ry_init(const char *host, const int port, const char *nod vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, m_host, cPort); releaseAllUnits(); conn = nopoll_conn_new(ctx, m_host, cPort, NULL, url, NULL, NULL); - //last_connect_sec = system32.timers; + g_conn = conn; } - return conn; + return TRUE; } bool CRYDevice::ry_run(void) @@ -1960,7 +1970,7 @@ bool CRYDevice::ry_run(void) if (isOk) { last_connect_sec = system32.timers; int msg_count = 0; - noPollMsg *msg[40]; + noPollMsg *msg[2048]; 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])) { @@ -1994,6 +2004,7 @@ bool CRYDevice::ry_run(void) vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, m_host, cPort); releaseAllUnits(); conn = nopoll_conn_new(ctx, m_host, cPort, NULL, url, NULL, NULL); + g_conn = conn; last_connect_sec = system32.timers; } } @@ -2012,7 +2023,7 @@ bool CRYDevice::ry_run(void) MakeYKFrame(conn, i); MakeYTFrame(conn, i); if (sec_changed) { - publishinitDeviceData(conn, i); + //publishinitDeviceData(conn, i); if ((last_sec % 60) == 0) { //更新数据 publishAnalogData(conn, i); publishStateData(conn, i); diff --git a/das-dn/cmg/ry.h b/das-dn/cmg/ry.h index a291be7f..53e01430 100644 --- a/das-dn/cmg/ry.h +++ b/das-dn/cmg/ry.h @@ -46,30 +46,17 @@ typedef std::unordered_map unitname2servicemap; typedef struct { std::string name; Json::Value value; + int highSpeed; } 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; class CRYDevice { public: CRYDevice(); ~CRYDevice(); - noPollConn *ry_init(const char*, const int, const char*, const char*); + BOOLEAN ry_init(const char*, const int, const char*, const char*); void ry_destroy(void); bool ry_run(void); private: @@ -81,8 +68,6 @@ private: LONG m_yxbwload = 0; LONG m_ycbwload = 0; - Snowflake m_sf = {1, 1, 0, 0}; - struSystem config_system32; struConfig config_config; struDatabase config_database; @@ -104,32 +89,6 @@ private: time_t last_sec; private: - 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; - } - std::vector split(const std::string &s, char delimiter); bool configInitializeMemory(void); diff --git a/das-dn/comm/process.cpp b/das-dn/comm/process.cpp index 6d668954..9775044c 100644 --- a/das-dn/comm/process.cpp +++ b/das-dn/comm/process.cpp @@ -1720,15 +1720,7 @@ BOOLEAN CProcess::Create(int id) } return TRUE; } -#if 0 -BOOLEAN CProcess::OnCreated(int id) -{ - m_bRunFlag = TRUE; - threadpool_add_task(&pool, main_run_process, this); - return TRUE; -} -#endif BOOLEAN CProcess::OnCreated(int id) { m_bRunFlag = TRUE; diff --git a/das-dn/comm/public.cpp b/das-dn/comm/public.cpp index 94ad07f0..90268937 100644 --- a/das-dn/comm/public.cpp +++ b/das-dn/comm/public.cpp @@ -53,6 +53,9 @@ char configfile[MAX_PATH] = "./conf/config.db"; //配置文件 QWORD system_timems; +noPollConn *g_conn; +Snowflake g_sf = {1, 1, 0, 0}; + static eLogLevel eLevelMax = LOG_DEBUG; //LOG_DEBUG; static const char* arszLevel2Str[] = { "NULL", "ERROR", "WARN", "INFO", "DEBUG" }; static pthread_t p_id[MAX_THREAD_NUM]; @@ -447,6 +450,46 @@ unionCP56Time Time_ttounionCP56Time(time_t st) return ct; } +QLONG filetime_to_unix(QLONG ft) +{ + uint64_t winTime = ft; + // 将100纳秒间隔转换为毫秒 + winTime /= 10000; + // 减去从1601年到1970年的毫秒数 + winTime -= 11644473600000LL; + // 将毫秒转换为秒 + return (winTime); +} + + +QWORD current_time() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); +} + +QWORD snowflake_next_id(void) +{ + QWORD timestamp = current_time(); + if (timestamp < g_sf.last_timestamp) { + return 0; + } + if (g_sf.last_timestamp == timestamp) { + g_sf.sequence = (g_sf.sequence + 1) & SEQUENCE_MASK; + if (g_sf.sequence == 0) { + while (current_time() <= g_sf.last_timestamp); + } + } else { + g_sf.sequence = 0; // reset sequence + } + g_sf.last_timestamp = timestamp; + return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) | + (g_sf.data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) | + (g_sf.worker_id << SEQUENCE_BITS) | + g_sf.sequence; +} + void alarm(void) { } diff --git a/das-dn/hostmodbustcp/host_modbus_tcp.cpp b/das-dn/hostmodbustcp/host_modbus_tcp.cpp index ad99e97f..38ec67a3 100644 --- a/das-dn/hostmodbustcp/host_modbus_tcp.cpp +++ b/das-dn/hostmodbustcp/host_modbus_tcp.cpp @@ -1,11 +1,13 @@ #include "host_modbus_tcp.h" - +#include +#include +#include +#include /////////////////////////////////////////////////////////////////////////////////// //Valid slave device addresses are in the range of 0 锟?C 247 decimal. // //The individual slave devices are assigned addresses in the range of 1 锟?C 247. // //Address 0 is used for the broadcast address, which all slave devices recognize.// /////////////////////////////////////////////////////////////////////////////////// -#define HAVE_FTP_PROCESS #ifdef HAVE_FTP_PROCESS #define MODBUSP_READ_ID 100 //读取文件及文件夹ID @@ -13,8 +15,435 @@ #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; + +typedef struct { + short point; + short pos; +} struDataPos; +typedef std::unordered_map datatypeposmap; +typedef std::unordered_map datatypemap; + +typedef struct +{ + int start; + int length; +} FIELDDES; + +struct { + int length; + int address; +} m_datalen_mbaddr[] = { + { 2, 200 }, + { 2, 201 }, + { 2, 202 }, + { 2, 203 }, + { 2, 204 }, + { 2, 205 }, + { 2, 206 }, + { 2, 207 }, + { 2, 209 }, + { 2, 210 }, + { 2, 208 }, + { 2, 211 }, + { 2, 212 }, + { 2, 213 }, + { 2, 214 }, + { 2, 215 }, + { 2, 216 }, + { 2, 217 }, + { 2, 218 }, + { 2, 219 }, + { 2, 220 }, + { 2, 221 }, + { 2, 222 }, + { 2, 223 }, + { 2, 224 }, + { 2, 225 }, + { 2, 226 }, + { 2, 227 }, + { 2, 228 }, + { 2, 229 }, + { 2, 230 }, + { 2, 231 }, + { 2, 232 }, + { 2, 233 }, + { 2, 234 }, + { 4, 235 }, + { 4, 237 }, + { 4, 239 }, + { 4, 241 }, + { 4, 243 }, + { 4, 245 }, + { 4, 247 }, + { 4, 249 }, + { 2, 251 }, + { 2, 252 }, + { 2, 253 }, + { 2, 254 }, + { 2, 255 }, + { 2, 256 }, + { 2, 257 }, + { 2, 258 }, + { 2, 259 }, + { 2, 260 }, + { 2, 261 }, + { 2, 262 }, + { 2, 263 }, + { 2, 264 }, + { 2, 265 }, + { 2, 266 }, + { 2, 267 }, + { 2, 268 }, + { 2, 269 }, + { 2, 270 }, + { 2, 271 }, + { 2, 272 }, + { 2, 273 }, + { 2, 274 }, + { 2, 275 }, + { 2, 276 }, + { 2, 277 }, + { 2, 278 }, + { 2, 279 }, + { 2, 280 }, + { 2, 281 }, + { 2, 282 }, + { 2, 283 }, + { 2, 284 }, + { 2, 285 }, + { 2, 286 }, + { 2, 287 }, + { 2, 288 }, + { 2, 289 }, + { 2, 290 }, + { 2, 291 }, + { 2, 292 }, + { 2, 293 }, + { 2, 294 }, + { 2, 295 }, + { 2, 296 }, + { 2, 297 }, + { 2, 298 }, + { 2, 299 }, + { 2, 300 }, + { 2, 301 }, + { 2, 302 }, + { 2, 303 }, + { 2, 304 }, + { 2, 305 }, + { 2, 306 }, + { 2, 307 }, + { 4, 308 }, + { 4, 310 }, + { 2, 312 }, + { 4, 313 }, + { 2, 315 }, + { 4, 316 }, + { 4, 318 }, + { 2, 320 }, + { 2, 321 }, + { 2, 322 }, + { 2, 323 }, + { 2, 324 }, + { 2, 325 }, + { 2, 326 }, + { 2, 327 }, + { 2, 328 }, + { 2, 329 }, + { 2, 330 }, + { 2, 331 }, + { 2, 332 }, + { 2, 333 }, + { 2, 334 }, + { 2, 335 }, + { 2, 336 }, + { 2, 337 }, + { 2, 338 }, + { 2, 339 }, + { 2, 340 }, + { 2, 341 }, + { 2, 342 }, + { 2, 343 }, + { 2, 344 }, + { 2, 345 }, + { 2, 346 }, + { 2, 347 }, + { 2, 348 }, + { 2, 349 }, + { 2, 350 }, + { 2, 351 }, + { 2, 352 }, + { 2, 353 }, + { 2, 354 }, + { 2, 355 }, + { 2, 356 }, + { 2, 357 }, + { 2, 358 }, + { 2, 359 }, + { 2, 360 }, + { 2, 361 } +}; + #include +static int websocket_write(const noPollConn* conn, const char * buffer, int buffer_len) +{ + int result; + result = nopoll_conn_send_text((noPollConn *)conn, (const char *)buffer, buffer_len); + /* ensure we have written all bytes but limit operation to 2 seconds */ + result = nopoll_conn_flush_writes((noPollConn *)conn, 2000000, result); + return (result == buffer_len) ? 0 : -1; +} + +static bool publish_sensor_data(const noPollConn* conn, 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()); + + jsonRoot["cmdId"] = str; + + Json::Int64 mtime = (Json::Int64)time(NULL); + mtime *= 1000; + jsonRoot["time"] = mtime; + jsonRoot["data"] = payload; + + std::string outputConfig = Json::writeString(builder, jsonRoot); + int rc = websocket_write(conn, outputConfig.c_str(), outputConfig.length()); + vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n%s\n", command, outputConfig.length(), outputConfig.c_str()); + if (rc != 0) { + vLog(LOG_DEBUG, "websocket write is error<%d>,insert into database.\n", rc); + //插入数据库 + return false; + } + + return true; +} + +static float GetUnitYCRealFromValue(int uid, int order, DWORD 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); +} + +BOOLEAN GetUnitYCIsFloat(int uid, int order) +{ + int udb; + float coef = 1.0f; + 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; + } + else + { + coef = pYC->coef; + } + + if (fabsf(coef) <= 1E-8) coef = 1.0f; + if (fabsf(coef - 1.0f) <= 1E-8) 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 BOOLEAN GetUnitYCType(int uid, int order) +{ + 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]; + return pYC->highSpeed; +} + +static WORD GetUnitYCRegisterAddr(int uid, int point) +{ + struUnit* pUnit; + struUnitYC* pYC; + + if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535; + pUnit = &config.units[uid]; + if (pUnit->yccount <= 0) return (WORD)65535; + if (point < 0 || point >= pUnit->yccount) return (WORD)65535; + pYC = &pUnit->ycs[point]; + return (MAKEWORD(pYC->m_param[1], pYC->m_param[2])); +} + +static WORD GetUnitYXRegisterAddr(int uid, int point) +{ + struUnit* pUnit; + struUnitYX* pYX; + + if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535; + pUnit = &config.units[uid]; + if (pUnit->yxcount <= 0) return (WORD)65535; + if (point < 0 || point >= pUnit->yxcount) return (WORD)65535; + pYX = &pUnit->yxs[point]; + return (MAKEWORD(pYX->m_param[1], pYX->m_param[2])); +} + +static BYTE GetUnitYXDataPos(int uid, int point) +{ + struUnit* pUnit; + struUnitYX* pYX; + + if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535; + pUnit = &config.units[uid]; + if (pUnit->yxcount <= 0) return (WORD)65535; + if (point < 0 || point >= pUnit->yxcount) return (WORD)65535; + pYX = &pUnit->yxs[point]; + return (pYX->m_param[3]); +} + +static BOOLEAN GetYCValue(const int order, const FIELDDES* fields, const char* pData, DWORD& value) +{ + if (pData == NULL) return FALSE; + if (fields == NULL) return FALSE; + if (order < 0 || order >= sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])) return FALSE; + int start = fields[order].start; + if (fields[order].length == sizeof(DWORD)) + { //4字节 + value = *(DWORD *)(pData + start); + return TRUE; + } + else if (fields[order].length == sizeof(WORD)) + { + WORD tmp = *(WORD *)(pData + start); + value = tmp; + return TRUE; + } + + return FALSE; +} + +static BOOLEAN GetYXValue(const int order, const FIELDDES* fields, const char* pData, const int pos, BOOLEAN& value) +{ + if (pData == NULL) return FALSE; + if (fields == NULL) return FALSE; + if (pos < 0 || pos >= 16) return FALSE; + if (order < 0 || order >= sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])) return FALSE; + int start = fields[order].start; + if (fields[order].length == sizeof(WORD)) + { + WORD tmp = *(WORD *)(pData + start); + WORD nTemp = 0x0001; + nTemp <<= pos; + if ((tmp) & nTemp) value = TRUE; + value = FALSE; + return TRUE; + } + + return FALSE; +} + +static bool publishhistoryHighSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values) +{ + if (uid < 0 || uid >= UNIT_NUM) return false; + Json::Value root; + if (values.size()) { + root["dataTime"] = (Json::Int64)dt; + root["deviceId"] = static_units[uid].deviceId; + root["values"] = values; + return publish_sensor_data(conn, "historyHighSpeedData", root); + } + return false; +} + +static bool publishhistoryLowSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values) +{ + if (uid < 0 || uid >= UNIT_NUM) return false; + Json::Value root; +#if 0 + 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] = GetUnitYCRealFromValue(uid, i, data[i]); + } + } +#endif + if (values.size()) { + root["dataTime"] = (Json::Int64)(dt / 1000 * 1000); //取整 + root["deviceId"] = static_units[uid].deviceId; + root["values"] = values; + return publish_sensor_data(conn, "historyLowSpeedData", root); + } + return false; +} + + +#define USE_MEMORY + +#ifdef USE_MEMORY + +struct memory { + char *response; + size_t size; +}; + +static size_t write_callback(void *ptr, size_t size, size_t nmemb, struct memory *mem) { + size_t new_size = mem->size + size * nmemb; + //fprintf(stderr, "mem is: %u", mem->response); + mem->response = (char *)realloc(mem->response, new_size + 1); + if (mem->response == NULL) { + fprintf(stderr, "Failed to allocate memory.\n"); + return 0; // Out of memory + } + memcpy(&(mem->response[mem->size]), ptr, size * nmemb); + mem->size = new_size; + mem->response[new_size] = '\0'; + return size * nmemb; +} + +#else + struct CustomProgress { curl_off_t lastruntime; @@ -57,8 +486,9 @@ static size_t writefunc(void* ptr, size_t size, size_t nmemb, FILE* stream) { return fwrite(ptr, size, nmemb, stream); } +#endif -static int ftpget(const char* remote, const char* local, const char* user, const char* pwd, const long timeout = 3) +static int ftpget(const char* remote, const char* local, const char* user, const char* pwd, const long timeout = 3, struct memory* chunk = NULL) { vLog(LOG_DEBUG, "start to get %s to local %s, with name: %s, and password: %s.\n", remote, local, user, pwd); curl_global_init(CURL_GLOBAL_ALL); @@ -67,10 +497,11 @@ static int ftpget(const char* remote, const char* local, const char* user, const char user_key[1024] = {0}; snprintf(user_key, sizeof(user_key), "%s:%s", user, pwd); + CURLcode ret = CURLE_GOT_NOTHING; +#ifndef USE_MEMORY FILE *file; curl_off_t local_file_len = -1; long filesize = 0; - CURLcode ret = CURLE_GOT_NOTHING; struct stat file_info; int use_resume = 0; @@ -78,12 +509,13 @@ static int ftpget(const char* remote, const char* local, const char* user, const local_file_len = file_info.st_size; use_resume = 1; } +#if 0 file = fopen(local, "ab+"); if (file == NULL) { vLog(LOG_ERROR, "open file error(%d,%s)\n", errno, strerror(errno)); return 0; } - +#endif curl_easy_setopt(curl, CURLOPT_URL, remote); curl_easy_setopt(curl, CURLOPT_USERPWD, user_key); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); @@ -94,8 +526,16 @@ static int ftpget(const char* remote, const char* local, const char* user, const curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); ret = curl_easy_perform(curl); fclose(file); - - vLog(LOG_DEBUG, "curl easy perform return value is: %d, and OK is: %d.\n", ret, CURLE_OK); +#else + curl_easy_setopt(curl, CURLOPT_URL, remote); + curl_easy_setopt(curl, CURLOPT_USERPWD, user_key); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)chunk); + curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); // Optional: depending on your FTP server + ret = curl_easy_perform(curl); +#endif + //vLog(LOG_DEBUG, "curl easy perform return value is: %d, and OK is: %d.\n", ret, CURLE_OK); int curl_state = 0; if (ret == CURLE_OK) curl_state = 1; else { @@ -116,19 +556,19 @@ static void* ryftp_process(void* param) CHostModbusTcpProcess* mbt = (CHostModbusTcpProcess *)param; //获取此协议配置里面的ftp信息 - char remote_filename[64]; - char remote_dirent[64]; +// char remote_filename[64]; +// char remote_dirent[64]; char remote[256]; - char name[128]; - char local_filename[64]; - char local_dirent[128]; + char name[256]; +// char local_filename[64]; +// char local_dirent[128]; //默认参数,或是通过协议配置获取 char user[128] = "administrator"; char password[128] = "123456"; char ipaddress[128] = "127.0.0.1"; - //根据协议创建一个本地协议目录 + //根据协议创s建一个本地协议目录 int pid = mbt->GetCurID(); if (pid < 0 || pid >= PROCESSES_NUM) return ((void*)0); char pathName[128]; @@ -140,13 +580,512 @@ static void* ryftp_process(void* param) snprintf(user, sizeof(user), "%s", mbt->m_user); snprintf(password, sizeof(password), "%s", mbt->m_password); #endif - char str[60]; DWORD target_addr = mbt->target_addr; + memset(ipaddress, '\0', sizeof(ipaddress)); + inet_ntop(AF_INET, &target_addr, ipaddress, 16); - memset(str, '\0', sizeof(str)); - inet_ntop(AF_INET, &target_addr, str, 16); + struct timespec start, end; + double elapsed_time = 0; + + 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]; + fields[len].start = reinterpret_cast(&t_data.localtime) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.localtime); + len++; + fields[len].start = reinterpret_cast(&t_data.iGenSpeed) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenSpeed); + len++; + fields[len].start = reinterpret_cast(&t_data.iGenPower) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenPower); + len++; + // + fields[len].start = reinterpret_cast(&t_data.iWindSpeed) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeed); + len++; + fields[len].start = reinterpret_cast(&t_data.iVibrationY) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iVibrationY); + len++; + fields[len].start = reinterpret_cast(&t_data.iVibrationZ) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iVibrationZ); + len++; + fields[len].start = reinterpret_cast(&t_data.iTurbineOperationMode) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTurbineOperationMode); + len++; + fields[len].start = reinterpret_cast(&t_data.iBPLevel) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBPLevel); + len++; + fields[len].start = reinterpret_cast(&t_data.iYPLevel) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iYPLevel); + len++; + fields[len].start = reinterpret_cast(&t_data.iGenSpeed1s) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenSpeed1s); + len++; + fields[len].start = reinterpret_cast(&t_data.iGenPower1s) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenPower1s); + len++; + fields[len].start = reinterpret_cast(&t_data.iWindSpeed1s) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeed1s); + len++; + fields[len].start = reinterpret_cast(&t_data.iGenToruqe1s) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenToruqe1s); + len++; + fields[len].start = reinterpret_cast(&t_data.iRotorSpeed) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iRotorSpeed); + len++; + fields[len].start = reinterpret_cast(&t_data.iTheoreticalPower) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTheoreticalPower); + len++; + fields[len].start = reinterpret_cast(&t_data.iReactivePower) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iReactivePower); + len++; + fields[len].start = reinterpret_cast(&t_data.iActivePowerSetPointValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iActivePowerSetPointValue); + len++; + fields[len].start = reinterpret_cast(&t_data.iCosPhiSetValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iCosPhiSetValue); + len++; + fields[len].start = reinterpret_cast(&t_data.iSetValueGenSpeed) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iSetValueGenSpeed); + len++; + fields[len].start = reinterpret_cast(&t_data.iSetValuePitchAngle) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iSetValuePitchAngle); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle1RefValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle1RefValue); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle2RefValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle2RefValue); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle3RefValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle3RefValue); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle1) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle1); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle2) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle2); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngle3) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngle3); + len++; + fields[len].start = reinterpret_cast(&t_data.iVaneDirection) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iVaneDirection); + len++; + fields[len].start = reinterpret_cast(&t_data.iWindDirection) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindDirection); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord01) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord01); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord02) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord02); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord03) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord03); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord04) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord04); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord05) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord05); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord06) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord06); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord07) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord07); + len++; + fields[len].start = reinterpret_cast(&t_data.StateWord08) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.StateWord08); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode01) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode01); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode02) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode02); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode03) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode03); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode04) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode04); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode05) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode05); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode06) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode06); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode07) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode07); + len++; + fields[len].start = reinterpret_cast(&t_data.ActiveStatusCode08) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.ActiveStatusCode08); + len++; + fields[len].start = reinterpret_cast(&t_data.iFrequency) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iFrequency); + len++; + fields[len].start = reinterpret_cast(&t_data.iUL1_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iUL1_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iUL2_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iUL2_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iUL3_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iUL3_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iIL1_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iIL1_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iIL2_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iIL2_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iIL3_690V) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iIL3_690V); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1MotorCurrent) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1MotorCurrent); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2MotorCurrent) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2MotorCurrent); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3MotorCurrent) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3MotorCurrent); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngleBk1) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngleBk1); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngleBk2) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngleBk2); + len++; + fields[len].start = reinterpret_cast(&t_data.iPitchAngleBk3) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iPitchAngleBk3); + len++; + fields[len].start = reinterpret_cast(&t_data.iCosPhi) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iCosPhi); + len++; + fields[len].start = reinterpret_cast(&t_data.iGearPressA) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGearPressA); + len++; + fields[len].start = reinterpret_cast(&t_data.iGearPressB) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGearPressB); + len++; + fields[len].start = reinterpret_cast(&t_data.iHydrPress) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iHydrPress); + len++; + fields[len].start = reinterpret_cast(&t_data.iNacellePositionLtd) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iNacellePositionLtd); + len++; + fields[len].start = reinterpret_cast(&t_data.iCableTwistTotal) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iCableTwistTotal); + len++; + fields[len].start = reinterpret_cast(&t_data.iNacellePositionTotal) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iNacellePositionTotal); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempOutdoor_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempOutdoor_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempHub_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempHub_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempNacelle_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempNacelle_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempTowerBase_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempTowerBase_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempCabinetNacelle_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempCabinetNacelle_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempCabinetTowerBase_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempCabinetTowerBase_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempTransformer690_400V_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempTransformer690_400V_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempMV_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempMV_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1TempMotor_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1TempMotor_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2TempMotor_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2TempMotor_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3TempMotor_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3TempMotor_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1TempBattBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1TempBattBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2TempBattBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2TempBattBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3TempBattBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3TempBattBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempCntr_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempCntr_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1TempInvBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1TempInvBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2TempInvBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2TempInvBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3TempInvBox_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3TempInvBox_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1TempPMMHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1TempPMMHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2TempPMMHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2TempPMMHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3TempPMMHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3TempPMMHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade1TempPMCHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade1TempPMCHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade2TempPMCHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade2TempPMCHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iBlade3TempPMCHeatsink_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iBlade3TempPMCHeatsink_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempRotorBearA_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempRotorBearA_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempRotorBearB_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempRotorBearB_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTemp1GearOil_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTemp1GearOil_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGearBearDE_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGearBearDE_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGearBearNDE_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGearBearNDE_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenBearDE_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenBearDE_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenBearNDE_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenBearNDE_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenStatorU_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenStatorU_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenStatorV_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenStatorV_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenStatorW_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenStatorW_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGenCoolingAir_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGenCoolingAir_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iAvailabillityToday) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iAvailabillityToday); + len++; + fields[len].start = reinterpret_cast(&t_data.iAvailabillityTotal) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iAvailabillityTotal); + len++; + fields[len].start = reinterpret_cast(&t_data.iKWhThisDay) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iKWhThisDay); + len++; + fields[len].start = reinterpret_cast(&t_data.iKWhOverall) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iKWhOverall); + len++; + fields[len].start = reinterpret_cast(&t_data.iOperationHoursDay) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iOperationHoursDay); + len++; + fields[len].start = reinterpret_cast(&t_data.iOperationHoursOverall) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iOperationHoursOverall); + len++; + fields[len].start = reinterpret_cast(&t_data.iLostKWhThisDay) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iLostKWhThisDay); + len++; + fields[len].start = reinterpret_cast(&t_data.iLostKWhOverall) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iLostKWhOverall); + len++; + fields[len].start = reinterpret_cast(&t_data.FirstTriggeredCode) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.FirstTriggeredCode); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW001) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW001); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW002) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW002); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW003) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW003); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW004) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW004); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW005) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW005); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW006) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW006); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW007) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW007); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW008) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW008); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW009) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW009); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW010) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW010); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW011) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW011); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW012) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW012); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW013) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW013); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW014) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW014); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW015) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW015); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW016) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW016); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW017) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW017); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW018) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW018); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW019) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW019); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW020) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW020); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW021) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW021); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW022) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW022); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW023) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW023); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW024) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW024); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW025) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW025); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW026) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW026); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW027) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW027); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW028) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW028); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW029) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW029); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW030) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW030); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW031) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW031); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW032) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW032); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW033) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW033); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW034) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW034); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW035) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW035); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW036) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW036); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW037) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW037); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW038) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW038); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW039) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW039); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW040) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW040); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW041) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW041); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW042) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW042); + len++; + + + //判断是否链接单元 + int uid = mbt->GetUnitID(0); //默认只接一个设备 + if (uid < 0 || uid >= UNIT_NUM) return ((void*)0); + + datatypemap highspeedmap; + datatypemap lowspeedmap; + 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); + if (GetUnitYCType(uid, i)) { + if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) { + highspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号,order-数据文件序号 + } + } else { + if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) { + lowspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号,order-数据文件序号 + } + } + } + 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); + BYTE data_pos = GetUnitYXDataPos(uid, i); + //fprintf(stderr, "register_addr is: %d, pos is: %d.\n", register_addr, data_pos); + struDataPos pos; + if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) { + pos.point = m_datalen2mbaddr_map[register_addr]; + pos.pos = data_pos; + yxdatamap.insert(datatypeposmap::value_type(i, pos)); //point-配置的序号,order-数据文件序号 + } + } + + //根据实际配置表将 - int i = 1; while (TRUE) { sleep(1); //每秒执行一次 //ftp获取文件 @@ -154,21 +1093,102 @@ static void* ryftp_process(void* param) //文件目录无效 continue; } - snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_currentFileNo); - snprintf(remote, sizeof(remote), "ftp://%s/data/rtdatalog/%d/%d", str, mbt->m_currentDirNo, mbt->m_currentFileNo); - if (ftpget(remote, name, user, password)) { + 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); + + clock_gettime(CLOCK_MONOTONIC, &start); + struct memory chunk = {0}; // For storing the downloaded data + if (ftpget(remote, name, user, password, 3, &chunk)) { //成功,处理文件 - vLog(LOG_DEBUG, "get a file, then send to ws.\n"); + struRYDeviceData *data = (struRYDeviceData *)chunk.response; + unionCP56Time st; + int uid = mbt->GetCurUnitID(); + for (int i = 0; i < 250; i++, data++) { + QLONG unix_time = filetime_to_unix(data->localtime); + DWORD localtime = ((unix_time / 1000) - 28800L); + + DWORD millisec = unix_time % 1000; + unix_time = localtime; unix_time *= 1000; + unix_time += millisec; + st = Time_ttounionCP56Time(localtime); + + //如何将结构化数据传入,且快速获取 + Json::Value highspeedvalues; + for (datatypemap::iterator it = highspeedmap.begin(); it != highspeedmap.end(); it++) { + //获取数据 + DWORD dvalue; + int order = it->first; + int point = it->second; + if (GetYCValue(point, fields, (const char *)data, dvalue)) { + //fprintf(stderr, "get<%d> value is: %d.\n", point, dvalue); +#if 0 + vLog(LOG_DEBUG, "datatime is: %04d-%02d-%02d %02d:%02d:%02d.%03d, value1 is: %d, value2 is: %d.\n", + st.year + 2000, st.month, st.dayofmonth, st.hour, st.minute, st.millisecond / 1000, + unix_time % 1000, + data->iGenSpeed, + data->iGenPower); +#endif + if (GetUnitYCIsFloat(uid, order)) { + highspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue); + } else { + highspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue; + } + } else { + highspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f; + } + } + publishhistoryHighSpeedData(g_conn, uid, unix_time, highspeedvalues); + + if (i % 25 == 0) { //40ms一个值,每25次位1s + Json::Value lowspeedvalues; + for (datatypemap::iterator it = lowspeedmap.begin(); it != lowspeedmap.end(); it++) { + //获取数据 + DWORD dvalue; + int order = it->first; + int point = it->second; + if (GetYCValue(point, fields, (const char *)data, dvalue)) { + //fprintf(stderr, "get<%d> value is: %d.\n", point, dvalue); + if (GetUnitYCIsFloat(uid, order)) { + lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue); + } else { + lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue; + } + } else { + lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f; + } + } + for (datatypeposmap::iterator it = yxdatamap.begin(); it != yxdatamap.end(); it++) { + BOOLEAN bvalue; + int order = it->first; + int point = it->second.point; + int pos = it->second.pos; + if (GetYXValue(point, fields, (const char *)data, pos, bvalue)) { + lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = (int)bvalue; + } else { + lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = 0; + } + } + publishhistoryLowSpeedData(g_conn, uid, unix_time, lowspeedvalues); + } + } + if (chunk.response) free(chunk.response); + //vLog(LOG_DEBUG, "get a file, then send to ws.\n"); + clock_gettime(CLOCK_MONOTONIC, &end); + elapsed_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; + vLog(LOG_DEBUG, "Elapsed time: %.6f seconds\n", elapsed_time); + mbt->m_lastFileNo = mbt->m_currentFileNo; mbt->m_currentFileNo++; if ((mbt->m_currentFileNo - mbt->m_lastStartFileNo) % 1000 == 0) { //一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0; mbt->m_currentDirNo++; mbt->m_lastStartFileNo = mbt->m_currentFileNo; +#if 0 if (mbt->m_currentDirNo >= 56) { //7天数据大约有56个文件夹 mbt->m_currentDirNo = 0; } +#endif //保存文件信息 } } @@ -269,7 +1289,7 @@ void CHostModbusTcpProcessItem::Release(void) CNetProcessItem::Release(); } -CHostModbusTcpProcess::CHostModbusTcpProcess(noPollConn *conn) +CHostModbusTcpProcess::CHostModbusTcpProcess() { m_nCount = 0; m_nFrameCount = 0; @@ -278,13 +1298,8 @@ CHostModbusTcpProcess::CHostModbusTcpProcess(noPollConn *conn) m_nCurBeginReg = 0; m_nNeedSend = FALSE; +#ifdef HAVE_FTP_PROCESS //websocket接口 - m_conn = NULL; - if (conn != NULL) - { - m_conn = conn; - } - m_pid = 0; //目录无效 @@ -294,6 +1309,7 @@ CHostModbusTcpProcess::CHostModbusTcpProcess(noPollConn *conn) m_currentFileNo = -1; //当前文件编号 m_lastDirNo = -1; //上一目录编号 m_lastFileNo = -1; //上一文件编号 +#endif } CHostModbusTcpProcess::~CHostModbusTcpProcess() @@ -625,7 +1641,10 @@ BOOLEAN CHostModbusTcpProcess::OnPreCreate(int id) m_nTimeout = 200; calc2(); - + + vLog(LOG_DEBUG, "file size is: %d\n", sizeof(struRYDeviceData) * 250 / 1024); + +#ifdef HAVE_FTP_PROCESS //启动后,创建ftp线程 if (m_pid <= 0) { vLog(LOG_DEBUG, "create a ftp thread.\n"); @@ -645,6 +1664,8 @@ BOOLEAN CHostModbusTcpProcess::OnPreCreate(int id) pthread_attr_destroy(&attr); } +#endif + return TRUE; } @@ -748,7 +1769,7 @@ BOOLEAN CHostModbusTcpProcess::OnTimer(void) if (pItem == NULL) return TRUE; m_nNeedSend = TRUE; -#if 1 +#ifdef HAVE_FTP_PROCESS //启动时读取一次,后面自己维护序号 if ((m_currentDirNo == -1) && (m_currentFileNo == -1)) { //当前文件和目录都为-1,程序第一次启动。需要获取ftp目录及文件ID @@ -1169,10 +2190,12 @@ 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); @@ -1214,10 +2237,9 @@ BOOLEAN CHostModbusTcpProcess::OnReceiveData(CHostModbusTcpProcessItem *pItem, B return FALSE; } +#ifdef HAVE_FTP_PROCESS BOOLEAN CHostModbusTcpProcess::OnReceiveIDData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { - int i; - int point; int uid; BYTE* pBuf; @@ -1249,10 +2271,16 @@ BOOLEAN CHostModbusTcpProcess::OnReceiveIDData(CHostModbusTcpProcessItem *pItem, //当前文件夹下第一个文件 m_lastStartFileNo = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); pBuf += 4; - vLog(LOG_DEBUG, "dir: %d, file: %d: start: %d\n", m_currentDirNo, m_currentFileNo, m_lastStartFileNo); +#if 0 + m_currentDirNo = 37; + m_currentFileNo = 26901; + m_lastStartFileNo = 26901; +#endif + vLog(LOG_DEBUG, "dir: %ld, file: %ld: start: %ld\n", m_currentDirNo, m_currentFileNo, m_lastStartFileNo); 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 54a29506..d21b50f2 100644 --- a/das-dn/hostmodbustcp/host_modbus_tcp.h +++ b/das-dn/hostmodbustcp/host_modbus_tcp.h @@ -4,10 +4,169 @@ #include "netproc.h" #include "modbus_def.h" +#define HAVE_FTP_PROCESS +#ifdef HAVE_FTP_PROCESS #include #include #include +#pragma pack(1) +typedef struct { + QLONG localtime;// PLC本地时间 8 none 0.0001 毫秒 little endian 系统 + WORD iGenSpeed;// 发电机转速 2 200 0.1 转/分 40ms 控制系统 + WORD iGenPower;// 机组有功功率 2 201 0.1 千瓦 40ms 控制系统 + WORD iWindSpeed;// 风速 2 202 0.01 米/秒 40ms 气象 + WORD iVibrationY;// 机舱振动前后方向 2 203 0.001 米/秒^2 40ms 机舱 + WORD iVibrationZ;// 机舱振动左右方向 2 204 0.001 米/秒^2 40ms 机舱 + WORD iTurbineOperationMode;// 运行模式 2 205 1 需要解析 1s 控制系统 + WORD iBPLevel;// 刹车等级 2 206 1 需要解析 1s 控制系统 + WORD iYPLevel;// 偏航运行模式 2 207 1 需要解析 1s 控制系统 + WORD iGenSpeed1s;// 发电机转速1秒均值 2 209 0.1 转/分 1s 控制系统 + WORD iGenPower1s;// 机组有功1秒均值 2 210 0.1 千瓦 1s 控制系统 + WORD iWindSpeed1s;// 风速1秒均值 2 208 0.01 米/秒 1s 控制系统 + WORD iGenToruqe1s;// 发电机扭矩1秒均值 2 211 0.1 牛米 1s 控制系统 + WORD iRotorSpeed;// 风轮转速 2 212 0.1 转/分 1s 控制系统 + WORD iTheoreticalPower;// 理论有功功率 2 213 0.1 千瓦 1s 控制系统 + WORD iReactivePower;// 无功功率 2 214 0.1 千乏 1s 控制系统 + WORD iActivePowerSetPointValue;// 有功设定值 2 215 0.1 千瓦 1s 控制系统 + WORD iCosPhiSetValue;// 功率因数设定值 2 216 0.001 . 1s 控制系统 + WORD iSetValueGenSpeed;// 发电机转速设定值 2 217 0.1 转/分 1s 控制系统 + WORD iSetValuePitchAngle;// 桨叶角度设定值 2 218 0.01 度 1s 控制系统 + WORD iPitchAngle1RefValue;// 桨叶1角度给定 2 219 0.01 度 1s 控制系统 + WORD iPitchAngle2RefValue;// 桨叶2角度给定 2 220 0.01 度 1s 控制系统 + WORD iPitchAngle3RefValue;// 桨叶3角度给定 2 221 0.01 度 1s 控制系统 + WORD iPitchAngle1;// 桨叶1角度 2 222 0.01 度 1s 变桨系统 + WORD iPitchAngle2;// 桨叶2角度 2 223 0.01 度 1s 变桨系统 + WORD iPitchAngle3;// 桨叶3角度 2 224 0.01 度 1s 变桨系统 + WORD iVaneDirection;// 机舱方向 2 225 0.1 度 1s 气象 + WORD iWindDirection;// 风向(与机舱夹角) 2 226 0.1 度 1s 气象 + WORD StateWord01;// 状态字01 2 227 1 需要解析 1s 控制系统 详细解析见 状态字解析 + WORD StateWord02;// 状态字02 2 228 1 需要解析 1s 控制系统 + WORD StateWord03;// 状态字03 2 229 1 需要解析 1s 控制系统 + WORD StateWord04;// 状态字04 2 230 1 需要解析 1s 控制系统 + WORD StateWord05;// 状态字05 2 231 1 需要解析 1s 控制系统 + WORD StateWord06;// 状态字06 2 232 1 需要解析 1s 控制系统 + WORD StateWord07;// 状态字07 2 233 1 需要解析 1s 控制系统 + WORD StateWord08;// 状态字08 2 234 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode01;// 故障代码01 4 235 1 需要解析 1s 控制系统 代表目前已经触发的故障代码类似:02(HH)04(HL)005(L) + DWORD ActiveStatusCode02;// 故障代码02 4 237 1 需要解析 1s 控制系统 详细解析见故障代码字解析 + DWORD ActiveStatusCode03;// 故障代码03 4 239 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode04;// 故障代码04 4 241 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode05;// 故障代码05 4 243 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode06;// 故障代码06 4 245 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode07;// 故障代码07 4 247 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode08;// 故障代码08 4 249 1 需要解析 1s 控制系统 + WORD iFrequency;// 电网频率 2 251 0.01 赫兹 1s 电网 + WORD iUL1_690V;// 电网L1相电压 2 252 0.1 伏 1s 电网 + WORD iUL2_690V;// 电网L2相电压 2 253 0.1 伏 1s 电网 + WORD iUL3_690V;// 电网L3相电压 2 254 0.1 伏 1s 电网 + WORD iIL1_690V;// 电网L1相电流 2 255 0.1 安 1s 电网 + WORD iIL2_690V;// 电网L2相电流 2 256 0.1 安 1s 电网 + WORD iIL3_690V;// 电网L3相电流 2 257 0.1 安 1s 电网 + WORD iBlade1MotorCurrent;// 变桨电机1电流 2 258 0.1 安 1s 变桨系统 + WORD iBlade2MotorCurrent;// 变桨电机2电流 2 259 0.1 安 1s 变桨系统 + WORD iBlade3MotorCurrent;// 变桨电机3电流 2 260 0.1 安 1s 变桨系统 + WORD iPitchAngleBk1;// 备用桨叶角度1 2 261 0.01 度 1s 变桨系统 + WORD iPitchAngleBk2;// 备用桨叶角度2 2 262 0.01 度 1s 变桨系统 + WORD iPitchAngleBk3;// 备用桨叶角度3 2 263 0.01 度 1s 变桨系统 + WORD iCosPhi;// 并网点功率因数 2 264 0.001 . 1s 电网 + WORD iGearPressA;// 齿轮箱油压A 2 265 0.1 巴 1s 齿轮箱 + WORD iGearPressB;// 齿轮箱油压B 2 266 0.1 巴 1s 齿轮箱 + WORD iHydrPress;// 液压系统压力 2 267 0.1 巴 1s 液压系统 + WORD iNacellePositionLtd;// 机舱绝对方向 2 268 0.1 度 1s 机舱 + WORD iCableTwistTotal;// 总扭缆角度 2 269 0.1 度 1s 机舱 + WORD iNacellePositionTotal;// 机舱方向 2 270 0.1 度 1s 机舱 + WORD iTempOutdoor_1sec;// 环境温度 2 271 0.1 摄氏度 1s 环境 + WORD iTempHub_1sec;// 轮毂内温度 2 272 0.1 摄氏度 1s 轮毂 + WORD iTempNacelle_1sec;// 机舱内温度 2 273 0.1 摄氏度 1s 机舱 + WORD iTempTowerBase_1sec;// 塔基内温度 2 274 0.1 摄氏度 1s 塔基 + WORD iTempCabinetNacelle_1sec;// 机舱柜内温度 2 275 0.1 摄氏度 1s 机舱 + WORD iTempCabinetTowerBase_1sec;// 塔基柜内温度 2 276 0.1 摄氏度 1s 塔基 + WORD iTempTransformer690_400V_1sec;// 400伏变压器温度 2 277 0.1 摄氏度 1s 塔基 + WORD iTempMV_1sec;// 箱变温度 2 278 0.1 摄氏度 1s 箱变 + WORD iBlade1TempMotor_1sec;// 变桨电机1温度 2 279 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempMotor_1sec;// 变桨电机2温度 2 280 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempMotor_1sec;// 变桨电机3温度 2 281 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempBattBox_1sec;// 变桨电池柜1温度 2 282 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempBattBox_1sec;// 变桨电池柜2温度 2 283 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempBattBox_1sec;// 变桨电池柜3温度 2 284 0.1 摄氏度 1s 变桨系统 + WORD iTempCntr_1sec;// 变桨中控箱温度 2 285 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempInvBox_1sec;// 变桨逆变器1温度 2 286 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempInvBox_1sec;// 变桨逆变器2温度 2 287 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempInvBox_1sec;// 变桨逆变器3温度 2 288 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempPMMHeatsink_1sec;// 变桨PMM1散热器温度 2 289 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempPMMHeatsink_1sec;// 变桨PMM2散热器温度 2 290 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempPMMHeatsink_1sec;// 变桨PMM3散热器温度 2 291 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempPMCHeatsink_1sec;// 变桨PMC1散热器温度 2 292 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempPMCHeatsink_1sec;// 变桨PMC2散热器温度 2 293 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempPMCHeatsink_1sec;// 变桨PMC3散热器温度 2 294 0.1 摄氏度 1s 变桨系统 + WORD iTempRotorBearA_1sec;// 主轴承A温度 2 295 0.1 摄氏度 1s 传动链 + WORD iTempRotorBearB_1sec;// 主轴承B温度 2 296 0.1 摄氏度 1s 传动链 + WORD iTemp1GearOil_1sec;// 齿轮箱油温 2 297 0.1 摄氏度 1s 齿轮箱 + WORD iTempGearBearDE_1sec;// 齿轮箱驱动齿轴承温度 2 298 0.1 摄氏度 1s 齿轮箱 + WORD iTempGearBearNDE_1sec;// 齿轮箱非驱动侧轴承温度 2 299 0.1 摄氏度 1s 发电机 + WORD iTempGenBearDE_1sec;// 发电机驱动侧轴承温度 2 300 0.1 摄氏度 1s 发电机 + WORD iTempGenBearNDE_1sec;// 发电机非驱动侧轴承温度 2 301 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorU_1sec;// 发电机绕组U温度 2 302 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorV_1sec;// 发电机绕组V温度 2 303 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorW_1sec;// 发电机绕组W温度 2 304 0.1 摄氏度 1s 发电机 + WORD iTempGenCoolingAir_1sec;// 发电机冷却风温度 2 305 0.1 摄氏度 1s 发电机 + WORD iAvailabillityToday;// 当天可利用率 2 306 0.001 . 1s 控制系统 + WORD iAvailabillityTotal;// 总可利用率 2 307 0.001 . 1s 控制系统 + DWORD iKWhThisDay;// 当天发电量 2 308 千瓦时 1s 控制系统 + DWORD iKWhOverall;// 总发电量 2 310 千瓦时 1s 控制系统 + WORD iOperationHoursDay;// 当天发电小时数 2 312 小时 1s 控制系统 + DWORD iOperationHoursOverall;// 总发电小时数 2 313 小时 1s 控制系统 + WORD iLostKWhThisDay;// 当天损失发电量 2 315 千瓦时 1s 控制系统 + DWORD iLostKWhOverall;// 总损失发电量 2 316 千瓦时 1s 控制系统 + DWORD FirstTriggeredCode;// 首触故障代码高 4 318 1 1s 控制系统 详细解析见故障代码字解析 + WORD SCW001;// 故障代码字01 2 320 1 1s 控制系统 + WORD SCW002;// 故障代码字02 2 321 1 1s 控制系统 + WORD SCW003;// 故障代码字03 2 322 1 1s 控制系统 + WORD SCW004;// 故障代码字04 2 323 1 1s 控制系统 + WORD SCW005;// 故障代码字05 2 324 1 1s 控制系统 + WORD SCW006;// 故障代码字06 2 325 1 1s 控制系统 + WORD SCW007;// 故障代码字07 2 326 1 1s 控制系统 + WORD SCW008;// 故障代码字08 2 327 1 1s 控制系统 + WORD SCW009;// 故障代码字09 2 328 1 1s 控制系统 + WORD SCW010;// 故障代码字10 2 329 1 1s 控制系统 + WORD SCW011;// 故障代码字11 2 330 1 1s 控制系统 + WORD SCW012;// 故障代码字12 2 331 1 1s 控制系统 + WORD SCW013;// 故障代码字13 2 332 1 1s 控制系统 + WORD SCW014;// 故障代码字14 2 333 1 1s 控制系统 + WORD SCW015;// 故障代码字15 2 334 1 1s 控制系统 + WORD SCW016;// 故障代码字16 2 335 1 1s 控制系统 + WORD SCW017;// 故障代码字17 2 336 1 1s 控制系统 + WORD SCW018;// 故障代码字18 2 337 1 1s 控制系统 + WORD SCW019;// 故障代码字19 2 338 1 1s 控制系统 + WORD SCW020;// 故障代码字20 2 339 1 1s 控制系统 + WORD SCW021;// 故障代码字21 2 340 1 1s 控制系统 + WORD SCW022;// 故障代码字22 2 341 1 1s 控制系统 + WORD SCW023;// 故障代码字23 2 342 1 1s 控制系统 + WORD SCW024;// 故障代码字24 2 343 1 1s 控制系统 + WORD SCW025;// 故障代码字25 2 344 1 1s 控制系统 + WORD SCW026;// 故障代码字26 2 345 1 1s 控制系统 + WORD SCW027;// 故障代码字27 2 346 1 1s 控制系统 + WORD SCW028;// 故障代码字28 2 347 1 1s 控制系统 + WORD SCW029;// 故障代码字29 2 348 1 1s 控制系统 + WORD SCW030;// 故障代码字30 2 349 1 1s 控制系统 + WORD SCW031;// 故障代码字31 2 350 1 1s 控制系统 + WORD SCW032;// 故障代码字32 2 351 1 1s 控制系统 + WORD SCW033;// 故障代码字33 2 352 1 1s 控制系统 + WORD SCW034;// 故障代码字34 2 353 1 1s 控制系统 + WORD SCW035;// 故障代码字35 2 354 1 1s 控制系统 + WORD SCW036;// 故障代码字36 2 355 1 1s 控制系统 + WORD SCW037;// 故障代码字37 2 356 1 1s 控制系统 + WORD SCW038;// 故障代码字38 2 357 1 1s 控制系统 + WORD SCW039;// 故障代码字39 2 358 1 1s 控制系统 + WORD SCW040;// 故障代码字40 2 359 1 1s 控制系统 + WORD SCW041;// 故障代码字41 2 360 1 1s 控制系统 + WORD SCW042;// 故障代码字42 2 361 1 1s 控制系统 +} struRYDeviceData; +#pragma pack() + +#endif + class CHostModbusTcpProcessItem : public CNetProcessItem { public: @@ -56,11 +215,12 @@ private: void sort1(STRUCT_PARAM*, int); //功能码排序 void sort2(STRUCT_PARAM*, int); //寄存地址排序 +#ifdef HAVE_FTP_PROCESS //增加websocket连接 pthread_t m_pid; + short m_uid; public: - noPollConn *m_conn; int m_iv; LONG m_currentDirNo; //当前目录编号 LONG m_currentFileNo; //当前文件编号 @@ -83,8 +243,10 @@ public: return 1; } +#endif + public: - CHostModbusTcpProcess(noPollConn *conn); + CHostModbusTcpProcess(); virtual ~CHostModbusTcpProcess(); CNetProcessItem *CreateItem(int ord); @@ -102,7 +264,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 68f8954e..a3b1b8eb 100644 --- a/das-dn/inc/public.h +++ b/das-dn/inc/public.h @@ -40,6 +40,8 @@ typedef int SOCKET; #include #include #include "zlog/zlog.h" +#include +#include #define MEMERY_1M 65536 //设置位64K #define DELAY_RUN 5000 @@ -405,6 +407,22 @@ typedef int SOCKET; #define MAX_TARGET_FORMULA_LEN 1024 #define FORMULA_STRING_LENGTH 200 + +#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; + #pragma pack(1) //for formulas @@ -861,6 +879,8 @@ typedef struct DWORD update_time; QLONG irn; + //是否高频属性, 0 - 不是, 1 - 是 + BOOLEAN highSpeed; //上界 float upBound; //下界 @@ -1278,9 +1298,8 @@ extern struMsgBuffer msgBuffer; extern struNodeOption nodes; extern char configpath[MAX_PATH]; //配置文件所在目录 extern char configfile[MAX_PATH]; //配置文件 -#if 0 -extern threadpool_t pool; -#endif + +extern noPollConn *g_conn; typedef struct { //网络配置信息 @@ -1309,53 +1328,6 @@ typedef struct #define MQTT_DEFAULT_PORT 1883 -#if 0 -typedef struct ANYWARN -{ - BYTE type; - BYTE warnType; -} ANYWARN, *PANYWARN; - -typedef struct YX_WARN { - BYTE type; - BYTE warnType; - BYTE unitID; - BYTE realVal; - short dotNo; - unionCP56Time warnTime; -} YX_WARN,*PYX_WARN; - -typedef struct YC_WARN { - BYTE type; - BYTE warnType; - BYTE unitID; - short dotNo; - float realVal; - unionCP56Time warnTime; -} YC_WARN, *PYC_WARN; - -typedef struct UNIT_WARN { - BYTE type; - BYTE warnType; - BYTE unitID; - BYTE realVal; - unionCP56Time warnTime; -} UNIT_WARN, *PUNIT_WARN; - -typedef union WARN { - ANYWARN any_warn; - YX_WARN yx_warn; - YC_WARN yc_warn; - UNIT_WARN unit_warn; -} WARN, *PWARN; - -typedef struct _tag_SEND_WARNBUF { - LONG total_warn; - LONG id; - WARN warn[1]; -} SEND_WARNBUF, *PSEND_WARNBUF; - -#endif #pragma pack() ////////////////////////////////////////////////////////////////////////// @@ -1372,6 +1344,7 @@ int unionCP56TimeToBuf(BYTE* buf, unionCP56Time st); int GetFileSize(const char* fname); time_t unionCP56TimetoTime_t(unionCP56Time* st); unionCP56Time Time_ttounionCP56Time(time_t st); +QLONG filetime_to_unix(QLONG ft); QWORD getTimeInMs(); ////////////////////////////////////////////////////////////////////////// typedef enum @@ -1390,6 +1363,7 @@ extern "C" void yk(void); void yt(void); void dumpLogs(void); + QWORD snowflake_next_id(void); BOOLEAN initialize_system(BOOLEAN, BOOLEAN, const char*, char*); BOOLEAN initialize_thread(void); BOOLEAN destroy_thread(void);