#include "host_modbus_tcp.h" #include #include #include #include #ifdef HAVE_FTP_PROCESS #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寄存器长度。 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, 208 }, { 2, 209 }, { 2, 210 }, { 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 }, { 2, 362 }, { 2, 363 }, { 2, 364 }, { 2, 365 }, { 2, 366 }, { 2, 367 }, { 2, 368 } }; #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", 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; CURL *curl; }; static int progressCallback(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { struct CustomProgress *progress = (struct CustomProgress *)p; CURL *curl = progress->curl; curl_off_t curtime = 0; curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &curtime); if ((curtime - progress->lastruntime) >= 3000000) { progress->lastruntime = curtime; fprintf(stderr, "Total time: %f\n", curtime); } fprintf(stderr, "UP: %ld bytes of %ld bytes, DOWN: %ld bytes of %ld bytes.\n", ulnow, ultotal, dlnow, dltotal); if (ultotal) fprintf(stderr, "UP progress: %0.2f\n", float(ulnow /ultotal)); if (dltotal) fprintf(stderr, "DOWN progress: %0.2f\n", float(dlnow /dltotal)); return 0; } static size_t getContentLengthFunc(void *ptr, size_t size, size_t nmemb, void *stream) { int r; long len = 0; r = sscanf((const char*)ptr, "Content-Length: %ld\n", &len); if (r) *((long *)stream) = len; return size * nmemb; } static size_t discardFunc(void *ptr, size_t size, size_t nmemb, void *stream) { return size * nmemb; } 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, struct memory* chunk = NULL) { //vLog(LOG_DEBUG, "start to get %s to local %s, with name: %s, and password: %s.\n", remote, local, user, pwd); curl_global_init(CURL_GLOBAL_ALL); CURL* curl = curl_easy_init(); char user_key[1024] = {0}; snprintf(user_key, sizeof(user_key), "%s:%s", user, pwd); CURLcode ret = CURLE_GOT_NOTHING; #ifndef USE_MEMORY FILE *file; curl_off_t local_file_len = -1; long filesize = 0; struct stat file_info; int use_resume = 0; if (stat(local, &file_info) == 0) { 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); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, getContentLengthFunc); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &filesize); curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, use_resume ? local_file_len : 0); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); ret = curl_easy_perform(curl); fclose(file); #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); #if 0 int curl_state = 0; if (ret == CURLE_OK) curl_state = 1; else { //vLog(LOG_ERROR, "%d,%s\n", ret, curl_easy_strerror(ret)); curl_state = 0; } #endif curl_easy_cleanup(curl); curl_global_cleanup(); return ret; } static void* ryftp_process(void* param) { if (param == NULL) return ((void*)0); CHostModbusTcpProcess* mbt = (CHostModbusTcpProcess *)param; //获取此协议配置里面的ftp信息 // char remote_filename[64]; // char remote_dirent[64]; char remote[256]; 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]; snprintf(pathName, sizeof(pathName), "%d", pid); if (mbt->_mkdir(pathName) < 0) return ((void*)0); //配置的用户名和密码 #if 0 snprintf(user, sizeof(user), "%s", mbt->m_user); snprintf(password, sizeof(password), "%s", mbt->m_password); #endif DWORD target_addr = mbt->target_addr; memset(ipaddress, '\0', sizeof(ipaddress)); inet_ntop(AF_INET, &target_addr, ipaddress, 16); #if 0 struct timespec start, end; double elapsed_time = 0; #endif 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.iWindSpeed_1sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iWindSpeed_1sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenSpeed_1sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenSpeed_1sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenPower_1sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenPower_1sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenToruqe_1sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenToruqe_1sec); 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++; fields[len].start = reinterpret_cast(&t_data.iGenSpeed_10sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenSpeed_10sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenSpeed_30sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenSpeed_30sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenPower_10sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenPower_10sec); len++; fields[len].start = reinterpret_cast(&t_data.iGenPower_30sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenPower_30sec); len++; fields[len].start = reinterpret_cast(&t_data.iWindSpeed_10sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iWindSpeed_10sec); len++; fields[len].start = reinterpret_cast(&t_data.iWindSpeed_30sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iWindSpeed_30sec); len++; fields[len].start = reinterpret_cast(&t_data.iAvailablePower) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iAvailablePower); 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-数据文件序号 } } //根据实际配置表将 WORD ftpget_retry_count = 0; while (TRUE) { sleep(1); //每秒执行一次 //ftp获取文件 if (mbt->m_iv == 1) { //文件目录无效 continue; } 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); #if 0 clock_gettime(CLOCK_MONOTONIC, &start); #endif 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); ftpget_retry_count = 0; 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); #if 0 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); #endif 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 //保存文件信息 } } else if (result == CURLE_REMOTE_FILE_NOT_FOUND) { //文件不存在,尝试60次(1分钟,正常情况下PLC10s生成一个文件) ftpget_retry_count++; if (ftpget_retry_count >= 60) { //重新通过modbus程序获取文件夹和最新文件信息 mbt->m_iv = 0; mbt->m_currentDirNo = -1; mbt->m_currentFileNo = -1; } } } pthread_exit(0); return ((void*)0); } #endif CHostModbusTcpProcessItem::CHostModbusTcpProcessItem() { m_nNum = 0; m_nFramePoll = 0; apdu_t0_begin = 1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); } CHostModbusTcpProcessItem::~CHostModbusTcpProcessItem() { m_nNum = 0; m_nFramePoll = 0; apdu_t0_begin = 1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); } void CHostModbusTcpProcessItem::AddFrames(struModbusExtFrame* yxs, struModbusExtFrame* ycs, struModbusExtFrame* yms) { int i = 0, j = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yxs[j].FrameType == 0 || yxs[j].FuncCode == 0 || yxs[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &yxs[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ycs[j].FrameType == 0 || ycs[j].FuncCode == 0 || ycs[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &ycs[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yms[j].FrameType == 0 || yms[j].FuncCode == 0 || yms[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &yms[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } } struModbusExtFrame* CHostModbusTcpProcessItem::GetNextFrame(void) { int last; if (m_nCurFrame >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) return NULL; if (m_nCurFrame < 0) m_nCurFrame = -1; last = m_nCurFrame; for (m_nCurFrame++; m_nCurFrame < MODBUS_RTU_AUTOMATIC_FRAME_MAX; m_nCurFrame++) { if (m_nModbusFrames[m_nCurFrame].FuncCode == 0 || m_nModbusFrames[m_nCurFrame].FrameType == 0) break; return &m_nModbusFrames[m_nCurFrame]; } for (m_nCurFrame = 0; m_nCurFrame <= last; m_nCurFrame++) { if (m_nModbusFrames[m_nCurFrame].FuncCode == 0 || m_nModbusFrames[m_nCurFrame].FrameType == 0) break; return &m_nModbusFrames[m_nCurFrame]; } return NULL; } void CHostModbusTcpProcessItem::Attach(int uid, int sock, DWORD peer_addr, WORD peer_port) { CNetProcessItem::Attach(uid, sock, peer_addr, peer_port); apdu_t0_begin = 1; m_nNum = 0; m_nFramePoll = 0; m_nCurFrame = 0; } void CHostModbusTcpProcessItem::Release(void) { apdu_t0_begin = 1; m_nNum = 0; m_nFramePoll = 0; m_nCurFrame = 0; CNetProcessItem::Release(); } CHostModbusTcpProcess::CHostModbusTcpProcess() { m_nCount = 0; m_nFrameCount = 0; m_nCurFrame = 0; m_nSendPoint = 0; 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; //上一文件编号 #endif } CHostModbusTcpProcess::~CHostModbusTcpProcess() { } CNetProcessItem *CHostModbusTcpProcess::CreateItem(int ord) { return dynamic_cast(new CHostModbusTcpProcessItem); } void CHostModbusTcpProcess::DestroyItem(int ord, BOOLEAN bDeleted /* = FALSE */) { CHostModbusTcpProcessItem *pItem = (CHostModbusTcpProcessItem *)GetItem(ord); if (pItem != NULL && !bDeleted) { delete pItem; return CNetProcess::DestroyItem(ord, TRUE); } return CNetProcess::DestroyItem(ord, bDeleted); } void CHostModbusTcpProcess::sort1(STRUCT_PARAM *params, int count) { int i, j, n; STRUCT_PARAM temp; n = count; for (i = 0; i < n - 1; ++i) //比较n-1轮 { for (j = 0; j < n - 1 - i; ++j) //每轮比较n-1-i次, { if (params[j].param[0] > params[j + 1].param[0]) { memcpy(&temp, ¶ms[j], sizeof(STRUCT_PARAM)); memcpy(¶ms[j], ¶ms[j + 1], sizeof(STRUCT_PARAM)); memcpy(¶ms[j + 1], &temp, sizeof(STRUCT_PARAM)); } } } } void CHostModbusTcpProcess::sort2(STRUCT_PARAM *params, int count) { int i, j, n; STRUCT_PARAM temp; n = count; for (i = 0; i < n - 1; ++i) //比较n-1轮 { for (j = 0; j < n - 1 - i; ++j) //每轮比较n-1-i次, { int addr1 = (int)MAKEWORD(params[j].param[1], params[j].param[2]); int addr2 = (int)MAKEWORD(params[j+1].param[1], params[j+1].param[2]); if (addr1 > addr2) { memcpy(&temp, ¶ms[j], sizeof(STRUCT_PARAM)); memcpy(¶ms[j], ¶ms[j + 1], sizeof(STRUCT_PARAM)); memcpy(¶ms[j + 1], &temp, sizeof(STRUCT_PARAM)); } } } } void CHostModbusTcpProcess::calc2(void) { int i, j, n, uid; BYTE addr; CHostModbusTcpProcessItem *pItem; for (i = 0; i < PROCESS_UNIT_NUM; i++) { pItem = (CHostModbusTcpProcessItem *)GetItem(i); if (NULL == pItem) continue; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) continue; if (GetUnitAddr(uid, &addr, 1)) { //获取单元地址成功,则该段原地址采用配置地址,否则该单元为无效地址。 pItem->m_addr = addr; } struModbusExtFrame ycframes[MODBUS_RTU_AUTOMATIC_FRAME]; struModbusExtFrame ymframes[MODBUS_RTU_AUTOMATIC_FRAME]; struModbusExtFrame yxframes[MODBUS_RTU_AUTOMATIC_FRAME]; memset(ycframes, 0, sizeof(ycframes)); memset(ymframes, 0, sizeof(ymframes)); memset(yxframes, 0, sizeof(yxframes)); struUnitModbusOption option; if (GetUnitOption(uid, &option, sizeof(option))) { if (option.use_owner_config) { //采用协议配置 if (option.modbus.yx1Enable) { yxframes[0].FrameType = MODBUSP_READ_YX1; yxframes[0].FuncCode = option.modbus.yx1FuncCode; yxframes[0].RegBegin = option.modbus.yx1Begin; yxframes[0].RegCount = option.modbus.yx1Count; } if (option.modbus.yx2Enable) { yxframes[1].FrameType = MODBUSP_READ_YX1; yxframes[1].FuncCode = option.modbus.yx2FuncCode; yxframes[1].RegBegin = option.modbus.yx2Begin; yxframes[1].RegCount = option.modbus.yx2Count; } if (option.modbus.yc1Enable) { ycframes[0].FrameType = MODBUSP_READ_YC1; ycframes[0].FuncCode = option.modbus.yc1FuncCode; ycframes[0].RegBegin = option.modbus.yc1Begin; ycframes[0].RegCount = option.modbus.yc1Count; } if (option.modbus.yc2Enable) { ycframes[1].FrameType = MODBUSP_READ_YC1; ycframes[1].FuncCode = option.modbus.yc2FuncCode; ycframes[1].RegBegin = option.modbus.yc2Begin; ycframes[1].RegCount = option.modbus.yc2Count; } if (option.modbus.yc3Enable) { ycframes[2].FrameType = MODBUSP_READ_YC1; ycframes[2].FuncCode = option.modbus.yc3FuncCode; ycframes[2].RegBegin = option.modbus.yc3Begin; ycframes[2].RegCount = option.modbus.yc3Count; } if (option.modbus.yc4Enable) { ycframes[3].FrameType = MODBUSP_READ_YC1; ycframes[3].FuncCode = option.modbus.yc4FuncCode; ycframes[3].RegBegin = option.modbus.yc4Begin; ycframes[3].RegCount = option.modbus.yc4Count; } if (option.modbus.ym1Enable) { ymframes[0].FrameType = MODBUSP_READ_YM1; ymframes[0].FuncCode = option.modbus.ym1FuncCode; ymframes[0].RegBegin = option.modbus.ym1Begin; ymframes[0].RegCount = option.modbus.ym1Count; } if (option.modbus.ym2Enable) { ymframes[1].FrameType = MODBUSP_READ_YM1; ymframes[1].FuncCode = option.modbus.ym2FuncCode; ymframes[1].RegBegin = option.modbus.ym2Begin; ymframes[1].RegCount = option.modbus.ym2Count; } //按寄存器排序 pItem->AddFrames(yxframes, ycframes, ymframes); continue; } } { int yccount, ymcount, yxcount; yccount = GetUnitYCCount(uid); ymcount = GetUnitYMCount(uid); yxcount = GetUnitYXCount(uid); STRUCT_PARAM *ycparam = NULL, *ymparam = NULL, *yxparam = NULL; if (yccount) ycparam = new STRUCT_PARAM[yccount]; if (ymcount) ymparam = new STRUCT_PARAM[ymcount]; if (yxcount) yxparam = new STRUCT_PARAM[yxcount]; #if 0 //插入一帧读取信息的报文 ycframes[0].FrameType = MODBUSP_READ_ID; ycframes[0].FuncCode = MODBUSP_READ_ID_FUNCCODE; ycframes[0].RegBegin = MODBUSP_READ_ID_REGISTER_ADDRESS; ycframes[0].RegCount = MODBUSP_READ_ID_REGISTER_LENGTH; j = 1; #else j = 0; #endif if (ycparam) { memset(ycparam, 0, sizeof(STRUCT_PARAM) * yccount); for (n = 0; n < yccount; n++) { memcpy(ycparam[n].param, GetUnitYCParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } //按功能码排序 sort1(ycparam, yccount); //按寄存器地址排序 sort2(ycparam, yccount); //组帧 for (n = 0; n < yccount; n++) { WORD addr = MAKEWORD(ycparam[n].param[1], ycparam[n].param[2]); if (addr >= 65535) continue; for (; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ycframes[j].FuncCode == 0) { ycframes[j].FrameType = MODBUSP_READ_YC1; ycframes[j].FuncCode = ycparam[n].param[0]; ycframes[j].RegBegin = addr; ycframes[j].RegCount = ycparam[n].param[3]; break; } if (ycframes[j].FuncCode == ycparam[n].param[0]) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + ycframes[j].RegBegin) { int len = addr - ycframes[j].RegBegin; if (len) { ycframes[j].RegCount = len + ycparam[n].param[3]; } else { vLog(LOG_DEBUG, "遥测测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } if (ymparam) { memset(ymparam, 0, sizeof(STRUCT_PARAM) * ymcount); for (n = 0; n < ymcount; n++) { memcpy(ymparam[n].param, GetUnitYMParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } sort1(ymparam, ymcount); sort2(ymparam, ymcount); //组帧 for (n = 0; n < ymcount; n++) { WORD addr = MAKEWORD(ymparam[n].param[1], ymparam[n].param[2]); if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ymframes[j].FuncCode == 0) { ymframes[j].FrameType = MODBUSP_READ_YM1; ymframes[j].FuncCode = ymparam[n].param[0]; ymframes[j].RegBegin = addr; ymframes[j].RegCount = ymparam[n].param[3]; break; } if (ymframes[j].FuncCode == ymparam[n].param[0]) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + ymframes[j].RegBegin) { int len = addr - ymframes[j].RegBegin; if (len) { ymframes[j].RegCount = len + ymparam[n].param[3]; } else { vLog(LOG_DEBUG, "遥脉测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } if (yxparam) { memset(yxparam, 0, sizeof(STRUCT_PARAM) * yxcount); for (n = 0; n < yxcount; n++) { memcpy(yxparam[n].param, GetUnitYXParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } sort1(yxparam, yxcount); sort2(yxparam, yxcount); //组帧 for (n = 0; n < yxcount; n++) { WORD addr = MAKEWORD(yxparam[n].param[1], yxparam[n].param[2]); if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yxframes[j].FuncCode == 0) { yxframes[j].FrameType = MODBUSP_READ_YX1; yxframes[j].FuncCode = yxparam[n].param[0]; yxframes[j].RegBegin = addr; yxframes[j].RegCount = 1; break; } if (yxframes[j].FuncCode == yxparam[n].param[0]) { int len = addr - yxframes[j].RegBegin; if (len) { if (yxframes[j].FuncCode == MODBUSC_F01 || yxframes[j].FuncCode == MODBUSC_F02) { if (addr <= MODBUS_MAX_BITMAP_REGISTER_NUM + yxframes[j].RegBegin) { yxframes[j].RegCount = len + 1; break; } } else if (yxframes[j].FuncCode == MODBUSC_F03 || yxframes[j].FuncCode == MODBUSC_F04) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + yxframes[j].RegBegin) { yxframes[j].RegCount = len + 1; break; } } } else { if (yxframes[j].FuncCode == MODBUSC_F01 || yxframes[j].FuncCode == MODBUSC_F02) { vLog(LOG_DEBUG, "遥信测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } //按寄存器排序 pItem->AddFrames(yxframes, ycframes, ymframes); } } } BOOLEAN CHostModbusTcpProcess::OnPreCreate(int id) { if (!CNetProcess::OnPreCreate(id)) return FALSE; m_nTimeout = 200; calc2(); #ifdef HAVE_FTP_PROCESS vLog(LOG_DEBUG, "file size is: %d\n", sizeof(struRYDeviceData) * 250 / 1024); //启动后,创建ftp线程 if (m_pid <= 0) { 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); 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); } #endif return TRUE; } BOOLEAN CHostModbusTcpProcess::Run(void) { int count; BYTE buffer[512]; if (!CNetProcess::Run()) return FALSE; FeedDog(); //process polling command CHostModbusTcpProcessItem *pItem = (CHostModbusTcpProcessItem *)GetItem(0); if (NULL == pItem) return TRUE; if (pItem->GetSock() < 0) { usleep(20000); return TRUE; } pItem = (CHostModbusTcpProcessItem *)GetCurItem(); if (NULL == pItem) return TRUE; buffer[0] = HIBYTE(pItem->m_nNum); buffer[1] = LOBYTE(pItem->m_nNum); buffer[2] = 0; buffer[3] = MB_TCP_PROTOCOL_ID; if ((m_nCurFrame == 0 && m_nNeedSend)) { count = 0; if (GetYKFrame(pItem, &buffer[6], count, m_nCurFrame, m_nCurFuncCode)) { //insert yk command } else if (GetYTFrame(pItem, &buffer[6], count, m_nCurFrame, m_nCurFuncCode)) { //insert yt command } else if (pItem->m_nFramePoll & MODBUSP_SET_TIME_FRAME) { pItem->m_nFramePoll &= ~MODBUSP_SET_TIME_FRAME; if (GetSetTimeFrame(pItem, &buffer[6], count)) { m_nCurFrame = 0; } } else if (pItem->m_nFramePoll & MODBUSP_GET_DATA_FRAME) { pItem->m_nFramePoll &= ~MODBUSP_GET_DATA_FRAME; if (GetReadDataFrame(pItem, &buffer[6], count)) { m_nCurFrame = m_nFrameType; } } if (count >= 2) { //发送前清除接收缓冲区所有数据 buffer[4] = HIBYTE(count); buffer[5] = LOBYTE(count); if (WriteData(buffer, count + 6, 0)) { DisplayTxData(buffer, count + 6, TRUE); } pItem->m_nNum++; m_nSendPoint = system32.ticks;//0; m_nNeedSend = FALSE; //fprintf(stderr, "tx<%d>: ", count+6); for (int a = 0; a < count+6; a++) fprintf(stderr, "%02X ", buffer[a]); fprintf(stderr, "\n"); FeedDog(); } } return TRUE; } BOOLEAN CHostModbusTcpProcess::OnTimer(void) { CHostModbusTcpProcessItem *pItem; if (!CNetProcess::OnTimer()) return FALSE; m_nCount++; pItem = (CHostModbusTcpProcessItem *)GetItem(0); if (NULL == pItem) return FALSE; if (pItem->GetSock() < 0) { if ((pItem->apdu_t0_begin + 30) < system32.timers) { pItem->apdu_t0_begin = system32.timers; Connect(pItem, 0, TRUE); } return TRUE; } if (m_nCurFrame != 0) { if (m_nSendPoint && (m_nSendPoint + m_nTimeout) <= system32.ticks) { //0.5 second command time out m_nSendPoint = 0; m_nCurFrame = 0; } } if (m_nCurFrame == 0 && (m_nCount % PollGap()) == 0) { pItem = (CHostModbusTcpProcessItem *)GetNextItem(); 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; } #endif struModbusExtFrame* frame = pItem->GetNextFrame(); if (frame != NULL) { m_nFrameType = frame->FrameType; m_nCurFuncCode = frame->FuncCode; m_nCurBeginReg = frame->RegBegin; m_nCurRegCount = frame->RegCount; pItem->m_nFramePoll |= MODBUSP_GET_DATA_FRAME; return TRUE; } } return TRUE; } BOOLEAN CHostModbusTcpProcess::GetYKFrame(CHostModbusTcpProcessItem *pItem, BYTE* pBuf, int& count, DWORD& frame, BYTE& FuncCode) { int uid; BYTE result; BYTE* pData; if (NULL == pItem) return FALSE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (NULL == pBuf) return FALSE; pData = pBuf; if (!GetUnitYK(uid, m_nYKOrder, m_bYKValue, m_nYKState, result)) { return FALSE; } vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is %s result is %s.\n", uid, m_nYKOrder, (m_bYKValue ? "ClOSE" : "TRIP"), val_to_str(m_nYKState, yk_state, "STATE = %d"), val_to_str(result, yk_result, "RESULT = %d")); BYTE* m_param; BYTE nFun; //功能码 BOOLEAN nNeedSelect; //遥控需要选择 WORD nReg, nVal; WORD nCloseSelReg, nCloseExecReg, nCloseEscReg, nCloseValue; //合闸命令参数 WORD nOpenSelReg, nOpenExecReg, nOpenEscReg, nOpenValue; //分闸命令参数 m_param = GetUnitYKParamByPoint(uid, m_nYKOrder); if (NULL == m_param) return FALSE; nFun = m_param[0]; //功能码占一个字节 nNeedSelect = m_param[1]; //遥控是否需要选择 nCloseSelReg = MAKEWORD(m_param[4], m_param[5]); //选择合寄存器 nCloseExecReg = MAKEWORD(m_param[6], m_param[7]); //执行合寄存器 nCloseEscReg = MAKEWORD(m_param[8], m_param[9]); //撤销合寄存器 nCloseValue = MAKEWORD(m_param[10], m_param[11]); //合 nOpenSelReg = MAKEWORD(m_param[12], m_param[13]); //选择分寄存器 nOpenExecReg = MAKEWORD(m_param[14], m_param[15]); //执行分寄存器 nOpenEscReg = MAKEWORD(m_param[16], m_param[17]); //撤销分寄存器 nOpenValue = MAKEWORD(m_param[18], m_param[19]); //分 if (m_nYKState == YKS_SELREQ) { //遥控选择 if (m_bYKValue) { nReg = nCloseSelReg; nVal = nCloseValue; } else { nReg = nOpenSelReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效,遥控无须选择 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_SELED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } else { pData[0] = pItem->m_addr; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; pData[4] = (nVal >> 8) & 0x00ff; pData[5] = nVal & 0x00ff; count = 6; FuncCode = nFun; frame = MODBUSP_YK_SELECT; return TRUE; } } else if (m_nYKState == YKS_EXEREQ) { //遥控执行 if (m_bYKValue) { nReg = nCloseExecReg; nVal = nCloseValue; } else { nReg = nOpenExecReg; nVal = nOpenValue; } if (0xffff == nReg) return FALSE; pData[0] = pItem->m_addr; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; pData[4] = (nVal >> 8) & 0x00ff; pData[5] = nVal & 0x00ff; count = 6; FuncCode = nFun; frame = MODBUSP_YK_EXECUTE; return TRUE; } else if (m_nYKState == YKS_ABRREQ) { //遥控撤销 if (m_bYKValue) { nReg = nCloseEscReg; nVal = nCloseValue; } else { nReg = nOpenEscReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } pData[0] = pItem->m_addr; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; pData[4] = (nVal >> 8) & 0x00ff; pData[5] = nVal & 0x00ff; count = 6; FuncCode = nFun; frame = MODBUSP_YK_CANCEL; return TRUE; } else if ((m_nYKState == YKS_SELING || m_nYKState == YKS_SELED) && result == YKR_OVER) { //遥控撤销 if (m_bYKValue) { nReg = nCloseEscReg; nVal = nCloseValue; } else { nReg = nOpenEscReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } pData[0] = pItem->m_addr; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; pData[4] = (nVal >> 8) & 0x00ff; pData[5] = nVal & 0x00ff; count = 6; FuncCode = nFun; frame = MODBUSP_YK_CANCEL; return TRUE; } return FALSE; } ////////////////////////////////////////////////////////////////////////// // yt start // ////////////////////////////////////////////////////////////////////////// BOOLEAN CHostModbusTcpProcess::GetYTFrame(CHostModbusTcpProcessItem *pItem, BYTE* pBuf, int& count, DWORD& frame, BYTE& FuncCode) { int uid; BYTE result; BYTE* pData; if (NULL == pItem) return FALSE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (NULL == pBuf) return FALSE; pData = pBuf; if (!GetUnitYT(uid, m_nYTOrder, m_dwYTValue, m_nYTState, result)) { return FALSE; } vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is %s result is %s.\n", uid, m_nYTOrder, m_dwYTValue, val_to_str(m_nYTState, yt_state, "STATE = %d"), val_to_str(result, yt_result, "RESULT = %d")); BYTE* m_param; BYTE nFun; //功能码 BYTE nSetType; //设置方式 0单寄存器,1双寄存器 BOOLEAN nNeedSelect; //遥设需要选择 WORD nReg = 0xffff; WORD nSelReg, nExecReg, nEscReg; //合闸命令参数 m_param = GetUnitYTParamByPoint(uid, m_nYTOrder); if (NULL == m_param) return FALSE; nSetType = m_param[0]; //0 16位整型值;1 32位整型值;2 32位浮点数值; nFun = m_param[1]; //功能码占一个字节 nNeedSelect = m_param[2]; //遥控是否需要选择 nSelReg = MAKEWORD(m_param[4], m_param[5]); //选择寄存器 nExecReg = MAKEWORD(m_param[6], m_param[7]); //执行寄存器 nEscReg = MAKEWORD(m_param[8], m_param[9]); //撤销寄存器 if (m_nYTState == YTS_SELREQ) { //遥设选择 nReg = nSelReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效,遥设无须选择 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_SELED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } else { FuncCode = nFun; frame = MODBUSP_YT_SELECT; } } else if (m_nYTState == YTS_EXEREQ) { //遥设执行 nReg = nExecReg; if (0xffff == nReg) return FALSE; FuncCode = nFun; frame = MODBUSP_YT_EXECUTE; } else if (m_nYTState == YTS_ABRREQ) { //遥设撤销 nReg = nEscReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } FuncCode = nFun; frame = MODBUSP_YT_CANCEL; } else if ((m_nYTState == YTS_SELING || m_nYTState == YTS_SELED) && result == YTR_OVER) { //遥设撤销 nReg = nEscReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } FuncCode = nFun; frame = MODBUSP_YT_CANCEL; } //modify by assouan for clean; pData[0] = pItem->m_addr; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; if (nFun == MODBUSC_F06) { pData[4] = (m_dwYTValue >> 8) & 0x00ff; pData[5] = m_dwYTValue & 0x00ff; count = 6; } else if (nFun == MODBUSC_F16) { if (nSetType == 0) { pData[4] = 0x00; pData[5] = 0x01; pData[6] = 0x02; pData[7] = (m_dwYTValue >> 8) & 0x00ff; pData[8] = m_dwYTValue & 0x00ff; count = 9; } else if (nSetType == 1) { pData[4] = 0x00; pData[5] = 0x02; pData[6] = 0x04; pData[7] = (m_dwYTValue >> 24) & 0x00ff; pData[8] = (m_dwYTValue >> 16) & 0x00ff; pData[9] = (m_dwYTValue >> 8) & 0x00ff; pData[10] = m_dwYTValue & 0x00ff; count = 11; } else if (nSetType == 2) { pData[4] = 0x00; pData[5] = 0x02; pData[6] = 0x04; pData[7] = (m_dwYTValue >> 8) & 0x00ff; pData[8] = m_dwYTValue & 0x00ff; pData[9] = (m_dwYTValue >> 24) & 0x00ff; pData[10] = (m_dwYTValue >> 16) & 0x00ff; count = 11; } } else return FALSE; return TRUE; } ////////////////////////////////////////////////////////////////////////// // yt end // ////////////////////////////////////////////////////////////////////////// BOOLEAN CHostModbusTcpProcess::GetSetTimeFrame(CHostModbusTcpProcessItem *pItem, BYTE* /*pData*/, int& /*count*/) { return TRUE; } BOOLEAN CHostModbusTcpProcess::GetReadDataFrame(CHostModbusTcpProcessItem *pItem, BYTE* pData, int& count) { if (NULL == pItem) return FALSE; if (m_nFrameType == 0) return FALSE; if (m_nCurFuncCode == 0) return FALSE; pData[0] = pItem->m_addr; pData[1] = (BYTE)m_nCurFuncCode; pData[2] = (m_nCurBeginReg >> 8) & 0x00ff; pData[3] = m_nCurBeginReg & 0x00ff; pData[4] = (m_nCurRegCount >> 8) & 0x00ff; pData[5] = m_nCurRegCount & 0x00ff; count = 6; return TRUE; } int CHostModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord) { int uid; if (count < 6) { //数据长度不足 return 0; } CHostModbusTcpProcessItem* pItem; pItem = (CHostModbusTcpProcessItem *)GetItem(ord); if (NULL == pItem) return -1; //头尾判断。 WORD protocol, len; protocol = MAKEWORD(pBuf[3], pBuf[2]); len = MAKEWORD(pBuf[5], pBuf[4]); if (count < len + 6) { //数据接收未完 return 0; } if (protocol != MB_TCP_PROTOCOL_ID) { //未知协议 return -1; } BYTE* buffer = &pBuf[6]; if (((buffer[1] & 0x7f) != MODBUSC_F01) && ((buffer[1] & 0x7f) != MODBUSC_F02) && ((buffer[1] & 0x7f) != MODBUSC_F03) && ((buffer[1] & 0x7f) != MODBUSC_F04) && ((buffer[1] & 0x7f) != MODBUSC_F05) && ((buffer[1] & 0x7f) != MODBUSC_F06) && ((buffer[1] & 0x7f) != MODBUSC_F07) && ((buffer[1] & 0x7f) != MODBUSC_F08) && ((buffer[1] & 0x7f) != MODBUSC_F11) && ((buffer[1] & 0x7f) != MODBUSC_F12) && ((buffer[1] & 0x7f) != MODBUSC_F15) && ((buffer[1] & 0x7f) != MODBUSC_F16) && ((buffer[1] & 0x7f) != MODBUSC_F17) && ((buffer[1] & 0x7f) != MODBUSC_F20) && ((buffer[1] & 0x7f) != MODBUSC_F21) && ((buffer[1] & 0x7f) != MODBUSC_F22) && ((buffer[1] & 0x7f) != MODBUSC_F23) && ((buffer[1] & 0x7f) != MODBUSC_F24) && ((buffer[1] & 0x7f) != MODBUSC_F43) && ((buffer[1] & 0x7f) != MODBUSC_F26)) { //不支持的功能码 return -1; } if ((buffer[1] & 0x80) == 0x80) { //错误代码 m_nCurFrame = 0; } //根据地址查找单元id uid = GetUnitByAddr(buffer, 1); if (uid < 0 || uid >= UNIT_NUM) return (len + 6); int order = GetOrderByUnitID(uid); if (order < 0 || order >= PROCESS_UNIT_NUM) return (len + 6); pItem = (CHostModbusTcpProcessItem *)GetItem(order); if (NULL == pItem) return (len + 6); if (OnReceiveData(pItem, buffer, (len - 3))) { m_nCurFrame = 0; } DisplayRxData(pBuf, (len + 6), TRUE, uid); UnitFeedDog(uid); return (len + 6); } BOOLEAN CHostModbusTcpProcess::OnReceiveData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int uid; if (NULL == pItem) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; UnitFeedDog(uid); if (pData[1] == m_nCurFuncCode) { if (m_nCurFrame == MODBUSP_READ_YX1) { return OnReceiveYXData(pItem, &pData[3], count); } else if (m_nCurFrame == MODBUSP_READ_YC1) { return OnReceiveYCData(pItem, &pData[3], count); } else if (m_nCurFrame == MODBUSP_READ_YM1) { 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); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YK_SELECT == m_nCurFrame) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_SELED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YK_CANCEL == m_nCurFrame) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YT_EXECUTE == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_EXEED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } else if (MODBUSP_YT_SELECT == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_SELED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } else if (MODBUSP_YT_CANCEL == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } } return FALSE; } #ifdef HAVE_FTP_PROCESS BOOLEAN CHostModbusTcpProcess::OnReceiveIDData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int uid; BYTE* pBuf; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; pBuf = pData; /* 1)、路径信息是否有效 byte; 2)、当前文件夹路径名的后缀 dint,按照顺序增加1(转字符串时在前补0); 3)、当前文件夹下最后新文件的编号 dint; 4)、当前文件夹下第一个文件的编号 dint; 5)、当前文件夹下文件个数 dint; */ //路径有效性判断 int iv = ((pBuf[0] << 8) | pBuf[1]); pBuf += 2; m_iv = iv; if (iv) { vLog(LOG_DEBUG, "路径信息无效\n"); return FALSE; } //当前文件夹路径名 m_currentDirNo = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); pBuf += 4; //当前文件夹下最后新文件 m_currentFileNo = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); pBuf += 4; //当前文件夹下第一个文件 m_lastStartFileNo = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); pBuf += 4; vLog(LOG_DEBUG, "最新文件夹编号: %ld, 最新文件名编号: %ld: 最新文件夹中第一个文件的编号: %ld\n", m_currentDirNo, m_currentFileNo, m_lastStartFileNo); return TRUE; } #endif BOOLEAN CHostModbusTcpProcess::OnReceiveYXData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int uid; int i, j; int point; BYTE param[4]; WORD reg; BOOLEAN yxVal; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; reg = m_nCurBeginReg; param[0] = m_nCurFuncCode; if (MODBUSC_F03 == m_nCurFuncCode || MODBUSC_F04 == m_nCurFuncCode) { //03功能码读取Holdings WORD nValue; WORD nTemp = 0x0001; for (i = 0; i < count; i += 2) { nValue = (pData[i] << 8) | pData[i+1]; nTemp = 0x0001; param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); reg++; for (j = 0; j < 16; j++) { param[3] = j; point = GetUnitYXPointByParam(uid, param, 4); if (point >= 0) { yxVal = SPI_OFF; if ((nValue) & nTemp) { yxVal = SPI_ON; } SetUnitYX(uid, point, yxVal); } nTemp <<= 1; } } } else if (MODBUSC_F01 == m_nCurFuncCode || MODBUSC_F02 == m_nCurFuncCode) { //01 02功能码读取Coils和Status BYTE *nValue = pData; BYTE nTemp = 0x01; for (i = 0; i < count; i++) { nTemp = 0x01; for (j = 0; j < 8; j++) { param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); reg++; point = GetUnitYXPointByParam(uid, param, 3); if (point >= 0) { yxVal = SPI_OFF; if ((*nValue) & nTemp) { yxVal = SPI_ON; } SetUnitYX(uid, point, yxVal); } nTemp <<= 1; } nValue++; } } return TRUE; } BOOLEAN CHostModbusTcpProcess::OnReceiveYCData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int uid; int i; BYTE* pBuf; BYTE* pParam; BYTE param[8]; DWORD nValue = 0; LONG bin_value; float f_val; int point; WORD reg; BYTE reg_count, value_type, sign_mark; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; pBuf = pData; reg = m_nCurBeginReg; param[0] = m_nCurFuncCode; for (i = 0; i < count;) { param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); point = GetUnitYCPointByParam(uid, param, 3); if (point >= 0) { //获得合法点号 pParam = GetUnitYCParamByPoint(uid, point); if (pParam != NULL) { reg_count = pParam[3]; value_type = pParam[4]; sign_mark = pParam[5]; //vLog(LOG_DEBUG, "here count is: %d, value type is: %d, and ", reg_count, value_type); if ((1 == reg_count) && (2 == value_type)) { //16位归一化值 if (2 == value_type) { if (sign_mark == 0) nValue = (DWORD)(WORD)((pBuf[0] << 8) | pBuf[1]); else nValue = (DWORD)(short)((pBuf[0] << 8) | pBuf[1]); SetUnitYC(uid, point, (LONG)nValue); //vLog(LOG_DEBUG, "value is: %ld.\n", nValue); } else if (8 == value_type) { if (sign_mark == 0) nValue = (DWORD)(WORD)((pBuf[0] << 8) | pBuf[1]); else nValue = (DWORD)(short)((pBuf[0] << 8) | pBuf[1]); nValue = bcd_to_int((const BYTE*)&nValue, sizeof(WORD)); SetUnitYC(uid, point, (LONG)nValue); } pBuf += 2; i += 2; reg++; } else if (2 == reg_count) { //32位测量值 if (0 == value_type) { //浮点数,高位在第一个寄存器 nValue = (DWORD)(pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); //nValue = (DWORD)(f_val * 1000); } else if (1 == value_type) { nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); //nValue = (DWORD)(f_val * 1000); } else if (3 == value_type) { //归一化值,高位在第一个寄存器 nValue = (DWORD)(pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); SetUnitYC(uid, point, (LONG)nValue); //vLog(LOG_DEBUG, "value is: %ld.\n", nValue); } else if (4 == value_type) { //归一化值,高位在第二个寄存器 nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); SetUnitYC(uid, point, (LONG)nValue); } else if (5 == value_type) { nValue = (DWORD)(pBuf[3] << 24 | pBuf[2] << 16 | pBuf[1] << 8 | pBuf[0]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); } else if (6 == value_type) { //32位bcd数据高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); bin_value = (LONG)bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYC(uid, point, bin_value); } else if (7 == value_type) { //32位bcd数据高位在第二个寄存器 nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); bin_value = (LONG)bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYC(uid, point, bin_value); } pBuf += 4; i += 4; reg += 2; } } } else { pBuf += 2; i += 2; reg++; } } return TRUE; } BOOLEAN CHostModbusTcpProcess::OnReceiveYMData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count) { int i; int point; int uid; BYTE* pBuf; BYTE* pParam; BYTE nParam[4]; BYTE value_type; WORD reg; DWORD nValue = 0; float f_val; DWORD dw[2]; //双精度转换中间变量 double d_val; DWORD bin_value; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; pBuf = pData; reg = m_nCurBeginReg; nParam[0] = m_nCurFuncCode; for (i = 0; i < count; ) { nParam[1] = LOBYTE(reg); nParam[2] = HIBYTE(reg); point = GetUnitYMPointByParam(uid, nParam, 3); if (point >= 0) { //获得有效点号 pParam = GetUnitYMParamByPoint(uid, point); if (NULL != pParam) { //获得有效参数 value_type = pParam[4]; if (0 == value_type) { //16位无符号整型 nValue = (pBuf[0] << 8) | pBuf[1]; SetUnitYM(uid, point, nValue); pBuf += 2; i += 2; reg++; } else if (1 == value_type) { //32位无符号整型高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (2 == value_type) { //32位整型高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (3 == value_type) { //32位无符号整型高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (4 == value_type) { //32位整型高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (5 == value_type) { //32位浮点数高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)f_val); pBuf += 4; reg += 2; i += 4; } else if (6 == value_type) { //32位浮点数高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)f_val); pBuf += 4; reg += 2; i += 4; } else if (7 == value_type) { //64位浮点数高位在第一个寄存器 dw[1] = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); dw[0] = (DWORD)((pBuf[6] << 24) | (pBuf[7] << 16) | (pBuf[4] << 8) | pBuf[5]); memcpy(&d_val, dw, 8); SetUnitYM(uid, point, (DWORD)(d_val)); pBuf += 8; reg += 4; i += 8; } else if (8 == value_type) { dw[0] = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); dw[1] = (DWORD)((pBuf[6] << 24) | (pBuf[7] << 16) | (pBuf[4] << 8) | pBuf[5]); memcpy(&d_val, dw, 8); SetUnitYM(uid, point, (DWORD)(d_val)); pBuf += 8; reg += 4; i += 8; } else if (9 == value_type) { nValue = (DWORD)((pBuf[3] << 24) | (pBuf[2] << 16) | (pBuf[1] << 8) | pBuf[0]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)(f_val * 10)); pBuf += 4; reg += 2; i += 4; } else if (10 == value_type) { //32位bcd数据 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYM(uid, point, bin_value); pBuf += 4; reg += 2; i += 4; } else { //无配置 pBuf += 2; reg++; i += 2; } } } else { pBuf += 2; i += 2; reg++; } } return TRUE; }