|
@@ -13,7 +13,7 @@
|
|
|
DecCondition::DecCondition()
|
|
|
{
|
|
|
ChannelID = -1;
|
|
|
- leaveNum = 0;
|
|
|
+ leaveTimeMaxNum = 0;
|
|
|
leaveNumOnTime = 0;
|
|
|
leaveOneTime = 0;
|
|
|
}
|
|
@@ -21,7 +21,7 @@ DecCondition::DecCondition()
|
|
|
DecCondition::DecCondition(const DecCondition& other)
|
|
|
{
|
|
|
ChannelID = other.ChannelID;
|
|
|
- leaveNum = other.leaveNum;
|
|
|
+ leaveTimeMaxNum = other.leaveTimeMaxNum;
|
|
|
leaveNumOnTime = other.leaveNumOnTime;
|
|
|
leaveOneTime = other.leaveOneTime;
|
|
|
}
|
|
@@ -31,7 +31,7 @@ DecCondition& DecCondition::operator=(const DecCondition& other)
|
|
|
if (this != &other)
|
|
|
{
|
|
|
ChannelID = other.ChannelID;
|
|
|
- leaveNum = other.leaveNum;
|
|
|
+ leaveTimeMaxNum = other.leaveTimeMaxNum;
|
|
|
leaveNumOnTime = other.leaveNumOnTime;
|
|
|
leaveOneTime = other.leaveOneTime;
|
|
|
}
|
|
@@ -46,7 +46,7 @@ RoomOnWorkInfo::RoomOnWorkInfo()
|
|
|
ChannelID = 0;
|
|
|
RoomID = 0;
|
|
|
CameraID = 0;
|
|
|
- RoomType = 0;
|
|
|
+ RoomType = Enum_RoomType::ROOM_NONE;
|
|
|
strRoomName = "";
|
|
|
StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
|
|
|
EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
|
|
@@ -101,7 +101,7 @@ void RoomOnWorkInfo::clear()
|
|
|
ChannelID = 0;
|
|
|
RoomID = 0;
|
|
|
CameraID = 0;
|
|
|
- RoomType = 0;
|
|
|
+ RoomType = Enum_RoomType::ROOM_NONE;
|
|
|
strRoomName = "";
|
|
|
StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
|
|
|
EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
|
|
@@ -248,7 +248,11 @@ FuncOnAndOffJob::FuncOnAndOffJob()
|
|
|
|
|
|
FuncOnAndOffJob::~FuncOnAndOffJob()
|
|
|
{
|
|
|
-
|
|
|
+ if(m_pListAlarm != nullptr)
|
|
|
+ {
|
|
|
+ delete m_pListAlarm;
|
|
|
+ m_pListAlarm = nullptr;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -276,14 +280,14 @@ void FuncOnAndOffJob::task()
|
|
|
for(auto& it : m_funcThreadInfo.listRoomCamActInfo)
|
|
|
{
|
|
|
/* 判断是不是直播间 */
|
|
|
- if(it.RoomType == GConfig.liveRoomType)
|
|
|
+ if(it.RoomType == Enum_RoomType::ROOM_LIVE)
|
|
|
{
|
|
|
mapRoomCamActInfo.insert(std::make_pair(it.RoomID, it));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 获取当前频率的在岗离岗信息,在表格“tChannel”中 */
|
|
|
- if(!getCurrentFrequencyInfo(m_funcThreadInfo.ChannelID, m_nowChnDecCondition))
|
|
|
+ if(!getCurrentFrequencyInfo(m_funcThreadInfo.ChannelID, m_nowChnDetecRule))
|
|
|
{
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "获取当前频率信息失败, ChannelID:{}", m_funcThreadInfo.ChannelID);
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
|
|
@@ -407,11 +411,10 @@ void FuncOnAndOffJob::task()
|
|
|
} else
|
|
|
{
|
|
|
/* 离岗 */
|
|
|
+ offWorkProcess(pRoomOnWorkInfo, roomInfo);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -456,7 +459,16 @@ bool FuncOnAndOffJob::getCurrentFrequencyInfo(const int ChannelID, DecCondition&
|
|
|
|
|
|
/**
|
|
|
* @brief 人员在岗情况处理
|
|
|
- *
|
|
|
+ 1、判断上次是在岗还是离岗
|
|
|
+ (1) 上次是离岗,结束离岗报警,需要判断是否已经写入数据库
|
|
|
+ 1) 已经写入数据库,更新数据库报警记录,更新结束时间,清空内存中的报警记录,主要是清空PKID,置为0
|
|
|
+ 2) 还未写入数据库,打印个日志,不需要做什么操作
|
|
|
+ (2) 上次是在岗,更新数据,主要是更新图片
|
|
|
+ 1) 如果上次在岗记录已经写入数据库,判断人脸列表是否相等
|
|
|
+ 1) 不相等,更新数据库
|
|
|
+ 2) 相等,更新在岗时间
|
|
|
+ 2) 如果上次在岗记录还未写入数据库,直接写入数据库
|
|
|
+
|
|
|
* @param pRoomOnWorkInfo 这个是内存中的记录,是历史记录
|
|
|
* @param roomInfo
|
|
|
*/
|
|
@@ -514,7 +526,7 @@ void FuncOnAndOffJob::onWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<c
|
|
|
}
|
|
|
alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
|
|
|
alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
|
|
|
- alarmInfo.StartTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
|
|
|
+ alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
|
|
|
alarmInfo.ActionID = "";
|
|
|
alarmInfo.Is_OnWork = true;
|
|
|
alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
|
|
@@ -571,7 +583,19 @@ void FuncOnAndOffJob::onWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<c
|
|
|
}
|
|
|
|
|
|
|
|
|
-/* 人员离岗情况 */
|
|
|
+/**
|
|
|
+ * @brief 人员离岗情况处理
|
|
|
+ 1、判断上次是在岗还是离岗
|
|
|
+ (1) 上次是在岗,开启离岗报警,然后判断是否已经写入数据库,更新离岗时间
|
|
|
+ 1) 已经写入数据库,更新在岗结束,离岗开始
|
|
|
+ 2) 还未写入数据库,打印个日志,不需要做什么操作
|
|
|
+ (2) 上次是离岗,不需要做啥
|
|
|
+ 2、更新在岗离岗状态,主要是更新图片
|
|
|
+ 3、判断有没有写入数据库
|
|
|
+
|
|
|
+ * @param pRoomOnWorkInfo
|
|
|
+ * @param roomInfo
|
|
|
+ */
|
|
|
void FuncOnAndOffJob::offWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo)
|
|
|
{
|
|
|
if(true == pRoomOnWorkInfo->bOnWork)
|
|
@@ -593,7 +617,7 @@ void FuncOnAndOffJob::offWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<
|
|
|
SPDLOG_LOGGER_INFO(m_logger, "人员在岗结束,离岗开始,{}", m_strBaseInfo);
|
|
|
}
|
|
|
|
|
|
- pRoomOnWorkInfo->addOneLeaveTime(m_curTime, m_nowChnDecCondition.leaveTimeMaxNum);
|
|
|
+ pRoomOnWorkInfo->addOneLeaveTime(m_curTime, m_nowChnDetecRule.leaveTimeMaxNum);
|
|
|
auto strLeaveTime = pRoomOnWorkInfo->getLeaveTimeString();
|
|
|
if(strLeaveTime != "")
|
|
|
{
|
|
@@ -604,6 +628,124 @@ void FuncOnAndOffJob::offWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<
|
|
|
/* 上次是离岗 */
|
|
|
SPDLOG_LOGGER_DEBUG(m_logger, "{} 没有人员,可能离岗了", m_strBaseInfo);
|
|
|
}
|
|
|
+ if(!m_nowRoomOnWorkInfo.strImagePath.empty())
|
|
|
+ {
|
|
|
+ pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
|
|
|
+ }
|
|
|
+ /* 判断有没有写入数据库 */
|
|
|
+ if(pRoomOnWorkInfo->PKID == 0)
|
|
|
+ {
|
|
|
+ /* 没有写入数据库,现在写入 */
|
|
|
+
|
|
|
+ /* 判断单次离岗超时,计算时间差,leaveOneTime设置为0表示不启用检测 */
|
|
|
+ int nLeaveTime = pRoomOnWorkInfo->StartTime.secsTo(m_curTime);
|
|
|
+ if(nLeaveTime > m_nowChnDetecRule.leaveOneTime && m_nowChnDetecRule.leaveOneTime > 0)
|
|
|
+ {
|
|
|
+ AlarmInfo alarmInfo;
|
|
|
+ alarmInfo.appFunction = m_funcThreadInfo.appFunction;
|
|
|
+ alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
|
|
|
+ alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
|
|
|
+ alarmInfo.DeviceID = 0;
|
|
|
+ if(roomInfo.second.mapCameraAction.size() == 1)
|
|
|
+ {
|
|
|
+ alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
|
|
|
+ }
|
|
|
+ alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
|
|
|
+ alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
|
|
|
+ alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
|
|
|
+ alarmInfo.ActionID = "";
|
|
|
+ alarmInfo.Is_OnWork = false;
|
|
|
+ alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
|
|
|
+ if(alarmInfo.listPersonInfo.size() > 0)
|
|
|
+ {
|
|
|
+ alarmInfo.ActionDes = fmt::format("离岗人员[{}][{}],人员单次离岗时间超过{}秒", alarmInfo.getFaceIDListString(), alarmInfo.getFaceNameListString(), m_nowChnDetecRule.leaveOneTime);
|
|
|
+ }else {
|
|
|
+ alarmInfo.ActionDes = fmt::format("人员单次离岗时间超过{}秒", m_nowChnDetecRule.leaveOneTime);
|
|
|
+ }
|
|
|
+ /* 写入数据库 */
|
|
|
+ m_fromWebAPI->insertAlarmInfo(alarmInfo, pRoomOnWorkInfo->PKID);
|
|
|
+ if(pRoomOnWorkInfo->PKID > 0)
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "写入离岗报警成功,{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceNameListString());
|
|
|
+ }else {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "写入离岗报警失败,{}", m_strBaseInfo);
|
|
|
+ }
|
|
|
+ pRoomOnWorkInfo->listLeaveTime.clear();
|
|
|
+
|
|
|
+ /* 获取当前频率,应用的报警信息的最大PKID */
|
|
|
+ int maxPKID = 0;
|
|
|
+ m_fromWebAPI->getMaxAlarmPKID(m_funcThreadInfo.ChannelID, m_funcThreadInfo.appFunction, maxPKID);
|
|
|
+ if(maxPKID > 0)
|
|
|
+ {
|
|
|
+ std::string actionDes = "人员离岗了清空在岗人员信息,方便客户端显示";
|
|
|
+ /* 不知道这里为啥要单独获取PKID,按理说用上面返回的即可 */
|
|
|
+ if(m_fromWebAPI->clearOnWorkAlarmInfo(maxPKID, true, actionDes))
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "☆ {} 人员离岗了清空在岗人员信息,方便客户端显示", m_strBaseInfo);
|
|
|
+ } else {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "× {} 人员离岗了清空在岗人员信息失败", m_strBaseInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 判断多次频繁离岗 */
|
|
|
+ if((pRoomOnWorkInfo->listLeaveTime.size() >= m_nowChnDetecRule.leaveNumOnTime) &&
|
|
|
+ (m_nowChnDetecRule.leaveNumOnTime > 0) && (m_nowChnDetecRule.leaveTimeMaxNum > 0))
|
|
|
+ {
|
|
|
+ /* 计算距离第一次离岗时间长度 */
|
|
|
+ int nLeaveTime = pRoomOnWorkInfo->listLeaveTime.front().secsTo(m_curTime);
|
|
|
+ if(nLeaveTime <= m_nowChnDetecRule.leaveOneTime)
|
|
|
+ {
|
|
|
+ AlarmInfo alarmInfo;
|
|
|
+ alarmInfo.appFunction = m_funcThreadInfo.appFunction;
|
|
|
+ alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
|
|
|
+ alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
|
|
|
+ alarmInfo.DeviceID = 0;
|
|
|
+ if(roomInfo.second.mapCameraAction.size() == 1)
|
|
|
+ {
|
|
|
+ alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
|
|
|
+ }
|
|
|
+ alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
|
|
|
+ alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
|
|
|
+ alarmInfo.EventTime = pRoomOnWorkInfo->listLeaveTime.front().toString("yyyy-MM-dd hh:mm:ss").toStdString();
|
|
|
+ alarmInfo.ActionID = "";
|
|
|
+ alarmInfo.Is_OnWork = false;
|
|
|
+ alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
|
|
|
+ if(alarmInfo.listPersonInfo.size() > 0)
|
|
|
+ {
|
|
|
+ alarmInfo.ActionDes = fmt::format("离岗人员[{}],人员离岗([]秒内发生{}次离岗)",
|
|
|
+ alarmInfo.getFaceNameListString(), m_nowChnDetecRule.leaveOneTime, m_nowChnDetecRule.leaveNumOnTime);
|
|
|
+ }else {
|
|
|
+ alarmInfo.ActionDes = fmt::format("人员离岗({}秒内发生{}次离岗)", m_nowChnDetecRule.leaveOneTime, m_nowChnDetecRule.leaveNumOnTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 写入数据库报警表 */
|
|
|
+ m_fromWebAPI->insertAlarmInfo(alarmInfo, pRoomOnWorkInfo->PKID);
|
|
|
+ if(pRoomOnWorkInfo->PKID > 0)
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "写入离岗报警成功,{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceNameListString());
|
|
|
+ }else {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "写入离岗报警失败,{}", m_strBaseInfo);
|
|
|
+ }
|
|
|
+ pRoomOnWorkInfo->listLeaveTime.clear();
|
|
|
+
|
|
|
+ /* 获取当前频率,应用的报警信息的最大PKID */
|
|
|
+ int maxPKID = 0;
|
|
|
+ m_fromWebAPI->getMaxAlarmPKID(m_funcThreadInfo.ChannelID, m_funcThreadInfo.appFunction, maxPKID);
|
|
|
+ if(maxPKID > 0)
|
|
|
+ {
|
|
|
+ std::string actionDes = "人员离岗了清空在岗人员信息,方便客户端显示";
|
|
|
+ /* 不知道这里为啥要单独获取PKID,按理说用上面返回的即可 */
|
|
|
+ if(m_fromWebAPI->clearOnWorkAlarmInfo(maxPKID, true, actionDes))
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "☆ {} 人员离岗了清空在岗人员信息,方便客户端显示", m_strBaseInfo);
|
|
|
+ } else {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "× {} 人员离岗了清空在岗人员信息失败", m_strBaseInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -635,3 +777,31 @@ std::list<std::string> FuncOnAndOffJob::getCameraNameList(const std::map<int, st
|
|
|
}
|
|
|
return listCameraName;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+/* 创建报警记录 */
|
|
|
+// void FuncOnAndOffJob::createAlarmInfo(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo, std::string actionDes, AlarmInfo& alarmInfo)
|
|
|
+// {
|
|
|
+// if(pRoomOnWorkInfo == nullptr)
|
|
|
+// {
|
|
|
+// return;
|
|
|
+// }
|
|
|
+
|
|
|
+// alarmInfo.appFunction = m_funcThreadInfo.appFunction;
|
|
|
+// alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
|
|
|
+// alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
|
|
|
+// alarmInfo.DeviceID = 0;
|
|
|
+// if(roomInfo.second.mapCameraAction.size() == 1)
|
|
|
+// {
|
|
|
+// alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
|
|
|
+// }
|
|
|
+// alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
|
|
|
+// alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
|
|
|
+// alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
|
|
|
+// alarmInfo.ActionID = "";
|
|
|
+// alarmInfo.Is_OnWork = false;
|
|
|
+// alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
|
|
|
+// alarmInfo.ActionDes = actionDes;
|
|
|
+// }
|
|
|
+
|
|
|
+
|