diff --git a/include/HTGlobal.h b/include/HTGlobal.h index a77ef28..76f3081 100644 --- a/include/HTGlobal.h +++ b/include/HTGlobal.h @@ -58,18 +58,18 @@ extern TTcpSocket g_Tcp; extern ST_IEC104_CTRL g_IecCtrl; // socket linker info and status extern mutex g_IecCtrl_mutex; // socket linker on mutex -extern map g_map_work; // 主变工作状态缓存 -extern mutex g_map_work_mutex; // 主变工作状态缓存队列锁 +extern map g_map_work; // 主变工作状态缓存 +extern mutex g_map_work_mutex; // 主变工作状态缓存队列锁 //extern map g_map_byq; // 变压器缓存数据 -extern map g_map_thres_byq; // 变压器缓存数据 -extern mutex g_map_byq_mutex; // 变压器缓存数据信息队列锁 +extern map g_map_thres_byq; // 变压器缓存数据 +extern mutex g_map_byq_mutex; // 变压器缓存数据信息队列锁 //extern map g_map_gis; // GIS缓存数据 //extern mutex g_map_gis_mutex; // GIS缓存数据信息队列锁 -extern multimap g_map_relation; // 主设备与外挂设备关系 -extern mutex g_map_relation_mutex; // GIS缓存数据信息队列锁 +extern multimap g_map_relation; // 主设备与外挂设备关系 +extern mutex g_map_relation_mutex; // GIS缓存数据信息队列锁 //extern map g_map_gis_104; // GIS最近一次104上传数据缓存 //extern mutex g_map_gis_104_mutex; @@ -77,26 +77,27 @@ extern mutex g_map_relation_mutex; // GIS //extern map g_map_blq; // BLQ缓存数据 //extern mutex g_map_blq_mutex; // BLQ缓存数据信息队列锁 -extern map g_map_iec; // 104报文解析缓存数据 -extern mutex g_map_iec_mutex; // 104报文解析缓存数据信息队列锁 +extern map g_map_iec; // 104报文解析缓存数据 +extern mutex g_map_iec_mutex; // 104报文解析缓存数据信息队列锁 -extern map g_map_devices; // 104报文解析缓存数据 -extern map g_map_iec_new; // 104报文解析缓存数据 -extern mutex g_map_iec_mutex_new; // 104报文解析缓存数据信息队列锁 +extern map g_map_devices; // 104报文解析缓存数据 +extern map g_map_iec_new; // 104报文解析缓存数据 +extern map g_map_dev_data; // 104点表报文解析缓存数据 +extern mutex g_map_iec_mutex_new; // 104报文解析缓存数据信息队列锁 -extern map g_map_sadr; // 点表匹配关系 -extern mutex g_map_sadr_mutex; +extern map g_map_sadr; // 点表匹配关系 +extern mutex g_map_sadr_mutex; -extern map g_map_img_thres; // 图片识别阈值 -extern mutex g_map_img_thres_mutex; +extern map g_map_img_thres; // 图片识别阈值 +extern mutex g_map_img_thres_mutex; //extern list g_list_monitor; // 监控消息数据队列 //extern mutex g_list_monitor_mutex; -extern map g_map_dev_time_stat; -extern mutex g_map_dev_time_stat_mutex; +extern map g_map_dev_time_stat; +extern mutex g_map_dev_time_stat_mutex; -extern map g_map_gis_state; // 断路器状态位与电流电压关系匹配表 -extern mutex g_map_gis_state_mutex; +extern map g_map_gis_state; // 断路器状态位与电流电压关系匹配表 +extern mutex g_map_gis_state_mutex; extern int g_seqno; // 与MEC之间交换的流水号 extern mutex g_seq_mutex; // 流水号 diff --git a/include/HTHP104Table.h b/include/HTHP104Table.h index 01b5c64..3082b17 100644 --- a/include/HTHP104Table.h +++ b/include/HTHP104Table.h @@ -13,6 +13,8 @@ #ifndef __HP104_TABLE #define __HP104_TABLE +#include + static const char IEC_CONFIMG_FILE[] = "../etc/ht_iec104.conf"; #pragma pack (push ,1) @@ -46,13 +48,25 @@ typedef struct tagIEC_DEVICE unsigned char one_dtime; }IEC_DEVICE; + typedef struct tagIEC_FIELD { std::string name; - float value; + float fval; time_t ts; } IEC_FIELD; + +typedef struct tagCACHED_DEV_DATA +{ + IEC_DEVICE* device; + time_t firstTs; + size_t assignedFields; + + std::map > fields; + +}CACHED_DEV_DATA; + typedef struct tagIEC_POINT { unsigned int sadr; // 信息体地址,map.key diff --git a/include/HTMemCacheData.h b/include/HTMemCacheData.h index 99f9eec..734408c 100644 --- a/include/HTMemCacheData.h +++ b/include/HTMemCacheData.h @@ -105,6 +105,11 @@ unsigned char cGetByqDeviceFaultState(unsigned char *pszEqm_code); void SethDevTimeStat(unsigned char *sys_code, unsigned char ws); time_t GetDevTimeStat(unsigned char *sys_code, unsigned char *ws); +void ResetCachedDeviceData(); +std::string BuildSqlForDeviceData(CACHED_DEV_DATA& cachedDev); + +bool AssignValueToDeviceData(CACHED_DEV_DATA& cachedDev, const IEC_OBJVAL_NEW& val); + #pragma pack (pop) #endif // end diff --git a/src/HTGlobal.cpp b/src/HTGlobal.cpp index 5eab328..e341c11 100644 --- a/src/HTGlobal.cpp +++ b/src/HTGlobal.cpp @@ -48,6 +48,7 @@ mutex g_map_iec_mutex; // 104报文解析 map g_map_devices; // 104报文解析缓存数据 map g_map_iec_new; // 104点表报文解析缓存数据 +map g_map_dev_data; // 104点表报文解析缓存数据 mutex g_map_iec_mutex_new; // 104报文解析缓存数据信息队列锁 map g_map_sadr; // 点表匹配关系 diff --git a/src/HTIEC104.cpp b/src/HTIEC104.cpp index 6232530..bf27993 100644 --- a/src/HTIEC104.cpp +++ b/src/HTIEC104.cpp @@ -1429,17 +1429,13 @@ bool bSetPointTableValueYC(const std::vector& values) if (g_TConfig.shouldParseBusiData() != 0) { - time_t ts = 0; + // time_t ts = 0; std::map::const_iterator itPoint; - std::map::const_iterator itDev; - std::string fields, fieldValues; - - std::map > records; - std::map >::iterator itRecord; - std::vector::iterator itField; - - char dataBuf[32] = { 0 }; - IEC_FIELD field; + + bool assigned = false; + map::iterator itCachedDev; + std::string sql; + list::iterator itBusiData; mutex_lock(g_map_iec_mutex_new); for (std::vector::const_iterator it = values.begin(); it != values.end(); ++it) { @@ -1448,92 +1444,29 @@ bool bSetPointTableValueYC(const std::vector& values) { continue; } - itRecord = records.find(itPoint->second.sensor_id); - if (itRecord == records.end()) - { - itRecord = records.insert(records.end(), std::make_pair<>(itPoint->second.sensor_id, std::vector())); - } - - field.name = (const char*)itPoint->second.fieldName; - field.ts = it->dtime; - field.value = it->fval; - - itRecord->second.push_back(field); - } - std::string sql; - for (itRecord = records.begin(); itRecord != records.end(); ++itRecord) - { - itDev = g_map_devices.find(itRecord->first); - if (itDev == g_map_devices.end() || strlen((const char*)itDev->second.tableName) == 0) + itCachedDev = g_map_dev_data.find(itPoint->second.sensor_id); + if (itCachedDev == g_map_dev_data.end()) { continue; } - fields.clear(); - fieldValues.clear(); - sql.clear(); - - for (itField = itRecord->second.begin(); itField != itRecord->second.end(); ++itField) + assigned = AssignValueToDeviceData(itCachedDev->second, *it); + if (assigned) { - ts = itField->ts; - fields.append(itField->name); - fields.append(","); - - fieldValues.append("'"); - snprintf(dataBuf, sizeof(dataBuf), "%0.4f", itField->value); - fieldValues.append(dataBuf); - fieldValues.append("',"); - - if ((itDev->second.one_dtime == 0)) + if (itCachedDev->second.assignedFields == itCachedDev->second.fields.size()) { - fields.append((const char *)itPoint->second.fieldName); - fields.append("_time,"); - - fieldValues.append("FROM_UNIXTIME("); - snprintf(dataBuf, sizeof(dataBuf), "%lld", (long long)ts); - fieldValues.append(dataBuf); - fieldValues.append("),"); + sql = BuildSqlForDeviceData(itCachedDev->second); + + vPrtLogMsg(LOG_DEBUG, RET_OK, "Insert busi data %s", sql.c_str()); + + mutex_lock(g_list_busi_data_mutex); + itBusiData = g_list_busi_data.insert(g_list_busi_data.end(), std::string()); + itBusiData->swap(sql); + mutex_unlock(g_list_busi_data_mutex); } } - - sql = "INSERT INTO "; - sql.append((const char *)itDev->second.tableName); - sql.append("("); - sql.append((const char *)itDev->second.devidFieldName); - sql.append(","); - if (itDev->second.one_dtime != 0) - { - sql.append((const char *)itDev->second.dtimeFieldName); - sql.append(","); - } - sql.append(fields, 0, fields.size() - 1); - - sql.append(") VALUES("); - - snprintf(dataBuf, sizeof(dataBuf), "%u", itDev->second.sensor_id); - sql.append(dataBuf); - sql.append(","); - if (itDev->second.one_dtime != 0) - { - sql.append("FROM_UNIXTIME("); - snprintf(dataBuf, sizeof(dataBuf), "%lld", (long long)ts); - sql.append(dataBuf); - sql.append("),"); - } - - sql.append(fieldValues, 0, fieldValues.size() - 1); - sql.append(")"); - - vPrtLogMsg(LOG_DEBUG, RET_OK, "Insert busi data %s", sql.c_str()); - - std::list::iterator it; - mutex_lock(g_list_busi_data_mutex); - it = g_list_busi_data.insert(g_list_busi_data.end(), std::string()); - it->swap(sql); - mutex_unlock(g_list_busi_data_mutex); } - mutex_unlock(g_map_iec_mutex_new); } @@ -1839,9 +1772,19 @@ int DecodeMsgFormatI(unsigned char *msgbuf, unsigned int len, unsigned short sen break; case 100: // 总召唤命令 if (cause == 7) // 激活确认 - vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Confirmation, %d.", msgbuf[9] - 20); + { + if (g_TConfig.shouldParseBusiData() != 0) + { + ResetCachedDeviceData(); + } + vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Confirmation, %d.", msgbuf[9] - 20); + } else if (cause == 10) // 激活结束 { + if (g_TConfig.shouldParseBusiData() != 0) + { + ResetCachedDeviceData(); + } //SendMsgFormatS(sendno); // 总召唤结束发送S帧确认 vPrtLogMsg(LOG_DEBUG, RET_OK, "Recv Activation Termination, %d", msgbuf[9] - 20); } diff --git a/src/HTMemCacheData.cpp b/src/HTMemCacheData.cpp index a892232..c27a4d5 100644 --- a/src/HTMemCacheData.cpp +++ b/src/HTMemCacheData.cpp @@ -398,6 +398,8 @@ static void vLoadIECPointTableNew() IEC_POINT stPoint; IEC_DEVICE stSensor; size_t idx = 0; + map::iterator itCachedDev; + map::iterator itDev; while (row = pdbHandle->GetRecord(res)) { memset(&stPoint, 0x00, sizeof(IEC_POINT)); @@ -453,13 +455,141 @@ static void vLoadIECPointTableNew() // vPrtLogMsg(LOG_WARNG, RET_OK, "----TABLE %s oneTime=%u", (const char*)stSensor.tableName, (unsigned int)stSensor.one_dtime); mutex_lock(g_map_iec_mutex_new); + itDev = g_map_devices.find(stSensor.sensor_id); + if (itDev == g_map_devices.end()) + { + itDev = g_map_devices.insert(g_map_devices.end(), std::make_pair<>(stSensor.sensor_id, stSensor)); + } g_map_devices[stSensor.sensor_id] = stSensor; g_map_iec_new[stPoint.sadr] = stPoint; + itCachedDev = g_map_dev_data.find(stSensor.sensor_id); + if (itCachedDev == g_map_dev_data.end()) + { + CACHED_DEV_DATA cachedData; + cachedData.device = &(itDev->second); + cachedData.firstTs = 0; + cachedData.assignedFields = 0; + itCachedDev = g_map_dev_data.insert(g_map_dev_data.end(), std::make_pair<>(stSensor.sensor_id, cachedData)); + } + + IEC_FIELD stField; + stField.name = (const char*)stPoint.fieldName; + stField.ts = 0; + stField.fval = 0.0; + itCachedDev->second.fields[stPoint.sadr] = std::make_pair<>(stField, false); mutex_unlock(g_map_iec_mutex_new); } pdbHandle->FreeRecord(res); } +void ResetCachedDeviceData() +{ + map::iterator it; + std::map >::iterator itField; + + mutex_lock(g_map_iec_mutex_new); + for (it = g_map_dev_data.begin(); it != g_map_dev_data.end(); ++it) + { + it->second.firstTs = 0; + it->second.assignedFields = 0; + + for (itField = it->second.fields.begin(); itField != it->second.fields.end(); ++itField) + { + itField->second.first.ts = 0; + itField->second.first.fval = 0.0; + itField->second.second = false; + } + } + mutex_unlock(g_map_iec_mutex_new); +} + +std::string BuildSqlForDeviceData(CACHED_DEV_DATA& cachedDev) +{ + std::string fields, fieldValues, sql; + char dataBuf[32] = { 0 }; +#if __cplusplus < 201103L + std::map >::iterator it; + + for (it = cachedDev.fields.begin(); it != cachedDev.fields.end(); ++it) +#else + std::map >::const_iterator it; + + for (it = cachedDev.fields.cbegin(); it != cachedDev.fields.cend(); ++it) +#endif + { + fields.append(it->second.first.name); + fields.append(","); + + fieldValues.append("'"); + snprintf(dataBuf, sizeof(dataBuf), "%0.4f", it->second.first.fval); + fieldValues.append(dataBuf); + fieldValues.append("',"); + + if ((cachedDev.device->one_dtime == 0)) + { + fields.append(it->second.first.name); + fields.append("_time,"); + + fieldValues.append("FROM_UNIXTIME("); + snprintf(dataBuf, sizeof(dataBuf), "%lld", (long long)it->second.first.ts); + fieldValues.append(dataBuf); + fieldValues.append("),"); + } + } + + sql = "INSERT INTO "; + sql.append((const char *)cachedDev.device->tableName); + sql.append("("); + sql.append((const char *)cachedDev.device->devidFieldName); + sql.append(","); + if (cachedDev.device->one_dtime != 0) + { + sql.append((const char *)cachedDev.device->dtimeFieldName); + sql.append(","); + } + sql.append(fields, 0, fields.size() - 1); + + sql.append(") VALUES("); + + snprintf(dataBuf, sizeof(dataBuf), "%u", cachedDev.device->sensor_id); + sql.append(dataBuf); + sql.append(","); + if (cachedDev.device->one_dtime != 0) + { + sql.append("FROM_UNIXTIME("); + snprintf(dataBuf, sizeof(dataBuf), "%lld", (long long)cachedDev.firstTs); + sql.append(dataBuf); + sql.append("),"); + } + + sql.append(fieldValues, 0, fieldValues.size() - 1); + sql.append(")"); + + return sql; +} + +bool AssignValueToDeviceData(CACHED_DEV_DATA& cachedDev, const IEC_OBJVAL_NEW& val) +{ + std::map >::iterator it = cachedDev.fields.find(val.sadr); + if (it != cachedDev.fields.end()) + { + if (!(it->second.second)) + { + if (cachedDev.firstTs == 0) + { + cachedDev.firstTs = val.dtime; + } + cachedDev.assignedFields++; + it->second.first.fval = val.fval; + it->second.first.ts = val.dtime; + + return true; + } + } + + return false; +} + // 刷新设备更新时间 void SethDevTimeStat(unsigned char *sys_code, unsigned char ws) {