|
@@ -10,7 +10,7 @@
|
|
|
#include "commonDefine.h"
|
|
|
#include "ThreadAlarmManager.h"
|
|
|
#include "spdlog.h"
|
|
|
-#include <qdatetime.h>
|
|
|
+#include <QDateTime>
|
|
|
|
|
|
|
|
|
|
|
@@ -57,11 +57,11 @@ void CompareItemThread::threadTask()
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "{} 创建定时器失败", m_logBase);
|
|
|
}
|
|
|
|
|
|
- // SPDLOG_LOGGER_WARN(m_logger, "{} 创建定时器成功,开启定时器", m_logBase);
|
|
|
+ // SPDLOG_LOGGER_WARN(m_logger, "{} 创建定时器成功,开启定时器", m_logBase);
|
|
|
m_pTimer->setTimerType(Qt::PreciseTimer);
|
|
|
m_pTimer->setSingleShot(false); // 设置为非单次定时器
|
|
|
- m_pTimer->setInterval(50);
|
|
|
- m_eventLoop.connect(m_pTimer, &QTimer::timeout, this, &CompareItemThread::do_timeout);
|
|
|
+ m_pTimer->setInterval(30);
|
|
|
+ m_eventLoop.connect(m_pTimer, &QTimer::timeout, this, &CompareItemThread::do_timeout, Qt::DirectConnection);
|
|
|
m_pTimer->start();
|
|
|
|
|
|
|
|
@@ -147,39 +147,7 @@ void CompareItemThread::task()
|
|
|
/* 睡眠100ms */
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
- /* -------------------------------------------------------------------------------------
|
|
|
- * 更新对比项信息
|
|
|
- * ------------------------------------------------------------------------------------- */
|
|
|
- if(updateThreadInfoInternal())
|
|
|
- {
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "{} 暂停对比检测,更新对比项信息");
|
|
|
- m_threadInfo.compareItemInfo = m_threadInfoNew.compareItemInfo;
|
|
|
- initData();
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "{} 更新对比项信息完成,继续检测对比");
|
|
|
- }
|
|
|
-
|
|
|
- /* -------------------------------------------------------------------------------------
|
|
|
- * 更新数据
|
|
|
- * ------------------------------------------------------------------------------------- */
|
|
|
- if(!updateResultData())
|
|
|
- {
|
|
|
- continue;
|
|
|
- // return;
|
|
|
- }
|
|
|
-
|
|
|
- /* -------------------------------------------------------------------------------------
|
|
|
- * 处理数据,将报警信息给写报警数据的线程
|
|
|
- * ------------------------------------------------------------------------------------- */
|
|
|
- // processAlarmData();
|
|
|
-
|
|
|
- /* -------------------------------------------------------------------------------------
|
|
|
- * 将音量包数据发送到MQTT中
|
|
|
- * ------------------------------------------------------------------------------------- */
|
|
|
- sendResultData();
|
|
|
-
|
|
|
- /* 清除标志位 */
|
|
|
- clearUpdateFlags();
|
|
|
- SPDLOG_LOGGER_WARN(m_logger, "{} 发送对比项数据到MQTT中", m_logBase);
|
|
|
+ timerTask();
|
|
|
}
|
|
|
/* 清理数据 */
|
|
|
clearData();
|
|
@@ -189,6 +157,7 @@ void CompareItemThread::task()
|
|
|
/* 定时器任务 */
|
|
|
void CompareItemThread::timerTask()
|
|
|
{
|
|
|
+
|
|
|
/* -------------------------------------------------------------------------------------
|
|
|
* 更新对比项信息
|
|
|
* ------------------------------------------------------------------------------------- */
|
|
@@ -210,7 +179,7 @@ void CompareItemThread::timerTask()
|
|
|
return;
|
|
|
}
|
|
|
/* -------------------------------------------------------------------------------------
|
|
|
- * 处理数据,将报警信息给写报警数据的线程,直接由各个计算线程直接写入
|
|
|
+ * 处理数据,将报警信息给写报警数据的线程,现在直接由各个计算线程直接写入
|
|
|
* ------------------------------------------------------------------------------------- */
|
|
|
// processAlarmData();
|
|
|
|
|
@@ -220,7 +189,7 @@ void CompareItemThread::timerTask()
|
|
|
sendResultData();
|
|
|
/* 清除标志位 */
|
|
|
clearUpdateFlags();
|
|
|
- // SPDLOG_LOGGER_WARN(m_logger, "{} 发送对比项数据到MQTT中", m_logBase);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/* 初始化数据 */
|
|
@@ -240,10 +209,26 @@ bool CompareItemThread::initData()
|
|
|
destroyCompareThreads();
|
|
|
createCompareThreads();
|
|
|
|
|
|
- /* 获取计算噪音的线程 */
|
|
|
+ /* 创建计算噪音的线程 */
|
|
|
destroyNoiseDetectThreads();
|
|
|
createNoiseDetectThreads();
|
|
|
|
|
|
+ /* 获取创建实时音量包的线程 */
|
|
|
+ if(!getCreateDBThread())
|
|
|
+ {
|
|
|
+ // SPDLOG_LOGGER_ERROR(m_logger, "{} 获取创建实时音量线程失败", m_logBase);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // for(const auto& pThread : m_mapCreateDBThreads)
|
|
|
+ // {
|
|
|
+ // if(pThread.second == nullptr)
|
|
|
+ // {
|
|
|
+ // SPDLOG_LOGGER_ERROR(m_logger, "{} 获取创建实时音量线程失败,通道: {}", m_logBase, pThread.first);
|
|
|
+ // }else {
|
|
|
+ // SPDLOG_LOGGER_INFO(m_logger, "{} 获取创建实时音量线程成功,通道: {}", m_logBase, pThread.first);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
/* 初始化存储结果的数据结构 */
|
|
|
m_compareResult = CompareResult_t();
|
|
|
m_compareResult.compareItemID = m_threadInfo.compareItemInfo.nID;
|
|
@@ -257,6 +242,8 @@ bool CompareItemThread::initData()
|
|
|
oneRoadVolume.roadInfo = road; // 设置通道信息
|
|
|
oneRoadVolume.dateTime = QDateTime::currentDateTime(); // 初始化时间
|
|
|
m_compareResult.mapRoadVolumes.insert({road.nCompareRoadNum, oneRoadVolume});
|
|
|
+
|
|
|
+ m_mapRealTimeData.insert({road.nCompareRoadNum, std::list<OneDBData>()}); // 初始化实时数据
|
|
|
}
|
|
|
|
|
|
m_mapCDBUpdated.clear();
|
|
@@ -265,8 +252,8 @@ bool CompareItemThread::initData()
|
|
|
m_mapCDBUpdated.insert({it.nCompareRoadNum, false}); // 初始化更新标志位为false
|
|
|
}
|
|
|
|
|
|
- m_lastDetectPeriodUpdateTime = QDateTime::currentDateTime();
|
|
|
-
|
|
|
+ QDateTime currentTime = QDateTime::currentDateTime();
|
|
|
+ m_lastDetectPeriodUpdateTime = currentTime;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -278,8 +265,7 @@ void CompareItemThread::clearData()
|
|
|
destroyCompareThreads();
|
|
|
/* 销毁音量报警线程 */
|
|
|
destroyCalculateDBThreads();
|
|
|
- /* 移除噪音检测线程 */
|
|
|
- // removeNoiseDetectThreads();
|
|
|
+ /* 销毁噪音检测线程 */
|
|
|
destroyNoiseDetectThreads();
|
|
|
|
|
|
/* 移除使用到的录音通道 */
|
|
@@ -302,12 +288,17 @@ void CompareItemThread::clearData()
|
|
|
/* 定时器槽函数 */
|
|
|
void CompareItemThread::do_timeout()
|
|
|
{
|
|
|
+ std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
|
|
|
// SPDLOG_LOGGER_WARN(m_logger, "{} 定时器触发,开始执行定时任务", m_logBase);
|
|
|
if(m_pFromMQTT == nullptr)
|
|
|
{
|
|
|
initMQTT();
|
|
|
}
|
|
|
timerTask();
|
|
|
+
|
|
|
+ std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now();
|
|
|
+ std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "{} 定时器任务完成,耗时: {} ms", m_logBase, duration.count());
|
|
|
}
|
|
|
|
|
|
/* 初始化MQTT */
|
|
@@ -333,6 +324,45 @@ void CompareItemThread::initMQTT()
|
|
|
|
|
|
|
|
|
|
|
|
+/* 获取创建实时音量的线程,这个线程属于录音线程,不需要在这里移除和销毁 */
|
|
|
+bool CompareItemThread::getCreateDBThread()
|
|
|
+{
|
|
|
+ m_mapCreateDBThreads.clear();
|
|
|
+ QDateTime startTime = QDateTime::currentDateTime();
|
|
|
+ /* 先设置有多少录音通道 */
|
|
|
+ for(const auto& road : m_threadInfo.compareItemInfo.mapRoad)
|
|
|
+ {
|
|
|
+ m_mapCreateDBThreads.insert({road.nCompareRoadNum, nullptr}); // 初始化为nullptr
|
|
|
+ }
|
|
|
+ while(true)
|
|
|
+ {
|
|
|
+ bool isAllThreadsReady = true;
|
|
|
+ for(const auto& road : m_threadInfo.compareItemInfo.mapRoad)
|
|
|
+ {
|
|
|
+ CreateDBThread* pThread = ThreadMan.getCreateDBThread(road.scRoadInfo.nSoundCardNum, road.scRoadInfo.roadInfo.nRoadNum);
|
|
|
+ if(pThread != nullptr)
|
|
|
+ {
|
|
|
+ m_mapCreateDBThreads[road.nCompareRoadNum] = pThread;
|
|
|
+ // SPDLOG_LOGGER_INFO(m_logger, "{} 获取创建实时音量线程成功,通道: {}:{}", m_logBase, road.scRoadInfo.strSoundCardName.toStdString(), road.scRoadInfo.roadInfo.nRoadNum);
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ isAllThreadsReady = false;
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "{} 获取创建实时音量线程失败,通道: {}:{}", m_logBase, road.scRoadInfo.strSoundCardName.toStdString(), road.scRoadInfo.roadInfo.nRoadNum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(isAllThreadsReady)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ QDateTime currentTime = QDateTime::currentDateTime();
|
|
|
+ if(startTime.secsTo(currentTime) > 10) // 超过10秒还没有获取到线程,直接返回失败
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "{} 获取创建实时音量线程超时,通道: {}", m_logBase, m_threadInfo.compareItemInfo.strName.toStdString());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
|
|
|
/* 创建两个对比线程,主通道是第一个通道,其他都需要和主通道进行对比 */
|
|
@@ -513,54 +543,76 @@ void CompareItemThread::destroyNoiseDetectThreads()
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * @brief 更新数据
|
|
|
- * 更新数据逻辑:
|
|
|
- * 1、先从音量计算线程获取最新的音量包信息,如果没有全部更新,则等待下次获取,不进行后面的操作
|
|
|
- * 2、获取噪音检测线程的噪音信息和获取一致性信息的线程的结果无需关系是否是最新的
|
|
|
- *
|
|
|
+ 音量包更新逻辑:
|
|
|
+ 1、先从音量创建线程获取最新的音量包信息,固定n个音量包,音量包数量和发送速度有关系,一秒
|
|
|
+ 最大有30个音量包(由宏定义VOLUME_INFO_NUM决定),如果每次发送3个音量包,则100ms发送一次
|
|
|
+ 2、获取音量包直接从录音线程(CreateDBThread)获取,每次获取3个,循环等待所有通道获取完3个后
|
|
|
+ 进行发送
|
|
|
+ 3、客户端依赖音量包绘制波形,因此音量包尽可能地快速发送
|
|
|
+
|
|
|
+ 检测结果更新逻辑
|
|
|
+ 2、获取噪音检测线程的噪音信息和获取一致性信息的线程的结果无需关心是否是最新的
|
|
|
+
|
|
|
*/
|
|
|
bool CompareItemThread::updateResultData()
|
|
|
{
|
|
|
/* -------------------------------------------------------------------------------------
|
|
|
- * 先从音量计算数据中获取音量包信息和报警信息(静音、过载、反相)
|
|
|
+ * 先从音量计算数据中获取音量包信息,循环等待获取完成
|
|
|
* ------------------------------------------------------------------------------------- */
|
|
|
- for(auto& pair : m_mapCDBUpdated)
|
|
|
+ bool isAllUpdated = false;
|
|
|
+ while(isAllUpdated == false)
|
|
|
{
|
|
|
- if(pair.second == true)
|
|
|
- {
|
|
|
- /* 已经更新过了 */
|
|
|
- continue;
|
|
|
- }
|
|
|
- CalculateDBThread* pThread = m_mapCalculateDBThreads[pair.first];
|
|
|
- if(pThread == nullptr)
|
|
|
- {
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "{} 音量计算线程失效", m_logBase);
|
|
|
- continue;
|
|
|
- }
|
|
|
- /* 获取最新的音量数据,包括静音、过载、反向等报警信息 */
|
|
|
- if(!pThread->getlastVolumeInfo(m_compareResult.mapRoadVolumes[pair.first]))
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
+ for(auto& pair : m_mapCDBUpdated)
|
|
|
{
|
|
|
- continue; // 没有获取到最新数据,继续等待
|
|
|
- }
|
|
|
-
|
|
|
- // const OneRoadVolume_t& volume = m_compareResult.mapRoadVolumes[pair.first];
|
|
|
- // for(int i = 0; i < VOLUME_INFO_NUM; ++i)
|
|
|
- // {
|
|
|
- // fmt::print("LDB:{}, RDB:{}\n", volume.vecleftDB[i], volume.vecrightDB[i]);
|
|
|
- // }
|
|
|
+ if(pair.second == true)
|
|
|
+ {
|
|
|
+ /* 已经更新过了 */
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // CalculateDBThread* pThread = m_mapCalculateDBThreads[pair.first];
|
|
|
+ // if(pThread == nullptr)
|
|
|
+ // {
|
|
|
+ // SPDLOG_LOGGER_ERROR(m_logger, "{} 音量计算线程失效", m_logBase);
|
|
|
+ // continue;
|
|
|
+ // }
|
|
|
+ // /* 获取最新的音量包数据 */
|
|
|
+ // if(!pThread->getlastVolumeInfo(m_compareResult.mapRoadVolumes[pair.first]))
|
|
|
+ // {
|
|
|
+ // continue; // 没有获取到最新数据,继续等待
|
|
|
+ // }
|
|
|
+ CreateDBThread* pThread = m_mapCreateDBThreads[pair.first];
|
|
|
+ if(pThread == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "{} 获取音量创建线程失败,通道: {}", m_logBase, pair.first);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ /* 获取最新的音量包数据 */
|
|
|
+ if(!pThread->getLatestRealTimeResult(m_mapRealTimeData[pair.first], 3))
|
|
|
+ {
|
|
|
+ // SPDLOG_LOGGER_WARN(m_logger, "{} 获取最新音量值失败,通道: {}", m_logBase, pair.first);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- pair.second = true; // 设置更新标志位为true
|
|
|
- }
|
|
|
- /* 判断是否全部更新,如果没有则返回,等待下次再次获取 */
|
|
|
- for(auto& pair : m_mapCDBUpdated)
|
|
|
- {
|
|
|
- if(false == pair.second)
|
|
|
+ pair.second = true;
|
|
|
+ }
|
|
|
+ /* 判断是否全部更新,如果没有则返回,等待下次再次获取 */
|
|
|
+ isAllUpdated = true;
|
|
|
+ for(auto& pair : m_mapCDBUpdated)
|
|
|
{
|
|
|
- // SPDLOG_LOGGER_DEBUG(m_logger, "{} 音量计算线程数据未全部更新,等待下次获取", m_logBase);
|
|
|
- return false;
|
|
|
+ if(false == pair.second)
|
|
|
+ {
|
|
|
+ isAllUpdated = false;
|
|
|
+ // SPDLOG_LOGGER_DEBUG(m_logger, "{} 音量计算线程数据未全部更新,等待下次获取", m_logBase);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* -------------------------------------------------------------------------------------
|
|
|
+ * 获取静音、过载、反相的结果
|
|
|
+ * ------------------------------------------------------------------------------------- */
|
|
|
+
|
|
|
|
|
|
/* -------------------------------------------------------------------------------------
|
|
|
* 获取噪音计算的结果(从噪音对比线程中获取)
|
|
@@ -674,11 +726,12 @@ bool CompareItemThread::generateMQTTJsonData(const CompareResult_t& compareResul
|
|
|
|
|
|
for(const auto& roadVolume : compareResult.mapRoadVolumes)
|
|
|
{
|
|
|
+ const int roadNum = roadVolume.first;
|
|
|
nJson json1;
|
|
|
json1["soundCard_id"] = roadVolume.second.roadInfo.scRoadInfo.strSoundCardID.toStdString(); /* 声卡id和声卡通道id */
|
|
|
json1["soundCard_road_id"] = roadVolume.second.roadInfo.scRoadInfo.roadInfo.nRoadNum;
|
|
|
/* 对比项通道编号和名称 */
|
|
|
- json1["item_road_num"] = roadVolume.second.roadInfo.nCompareRoadNum;
|
|
|
+ json1["item_road_num"] = roadNum;
|
|
|
json1["item_road_name"] = roadVolume.second.roadInfo.strCompareRoadName.toStdString();
|
|
|
json1["similarity"] = roadVolume.second.similarity;
|
|
|
json1["is_silence"] = roadVolume.second.isSilence;
|
|
@@ -688,19 +741,18 @@ bool CompareItemThread::generateMQTTJsonData(const CompareResult_t& compareResul
|
|
|
json1["is_noise_warning"] = roadVolume.second.isNoiseWarning;
|
|
|
json1["is_consistency"] = roadVolume.second.isConsistency;
|
|
|
json1["is_not_consistency_warning"] = roadVolume.second.isNotConsistencyWarning;
|
|
|
- json1["left_real_time_db"] = roadVolume.second.leftRealTimeDB;
|
|
|
- json1["right_real_time_db"] = roadVolume.second.rightRealTimeDB;
|
|
|
/* 添加音量包信息 */
|
|
|
- for(const auto& db : roadVolume.second.vecleftDB)
|
|
|
+ auto& listRTData = m_mapRealTimeData[roadNum];
|
|
|
+ for(const auto& db : listRTData)
|
|
|
{
|
|
|
- json1["left_db_array"].push_back(db);
|
|
|
+ json1["left_db_array"].push_back(db.leftDB);
|
|
|
+ json1["right_db_array"].push_back(db.rightDB);
|
|
|
// fmt::print("left_db_array: {}\n", db);
|
|
|
}
|
|
|
- for(const auto& db : roadVolume.second.vecrightDB)
|
|
|
- {
|
|
|
- json1["right_db_array"].push_back(db);
|
|
|
- // fmt::print("right_db_array: {}\n", db);
|
|
|
- }
|
|
|
+ listRTData.clear();
|
|
|
+
|
|
|
+ // json1["left_real_time_db"] = m_mapRealTimeData[roadNum].leftDB;
|
|
|
+ // json1["right_real_time_db"] = m_mapRealTimeData[roadNum].rightDB;
|
|
|
|
|
|
/* 添加到基础信息中 */
|
|
|
json0["road_volumes"].push_back(json1);
|