123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #define NOMINMAX
- #include "./date/date.h"
- #include "HIKNvr.h"
- #include <ctime>
- #include <iostream>
- #include <chrono>
- HIKNvr::HIKNvr(){
- }
- /**
- * @brief Initializes the NVR with the given login information and channel.
- *
- * @param ip The IP address of the NVR.
- * @param port The port number of the NVR.
- * @param username The username for logging into the NVR.
- * @param password The password for logging into the NVR.
- * @param channel The channel number to set for the NVR.
- */
- bool HIKNvr::InitNvr(std::string ip, std::string port, std::string username, std::string password, int channel)
- {
- if (Login(ip, port, username, password) == 0){
- m_Channel = channel + 32;
- return true;
- }
- return false;
- }
- int HIKNvr::GetNvrUTCDiff(){
- NET_DVR_NETAPPCFG struNAC = {0};
- DWORD ZoneSize = 0;
- NET_DVR_GetDVRConfig(LoginID, NET_DVR_GET_NETAPPCFG, 0, &struNAC, sizeof(NET_DVR_NETAPPCFG), &ZoneSize);
- int nDiffHour = struNAC.struNtpClientParam.cTimeDifferenceH;
- int nDiffMin = struNAC.struNtpClientParam.cTimeDifferenceM;
- nDiffTotalMin = (nDiffHour < 0 ? -1 : 1) * (abs(nDiffHour) * 60 + nDiffMin);
- return (nDiffHour < 0 ? -1 : 1) * (abs(nDiffHour) * 60 + nDiffMin);
- }
- /**
- * @brief 用年和月查询日
- *
- * @param select_time The selected time.
- * @param available_date_vec The available date vector.
- * @return true if the time region is found, false otherwise.
- */
- int HIKNvr::CheckTimeRegionWithMonth(DateTime select_time,std::vector<int>& available_date_vec)
- {
- DateTime DateNow(select_time);
- // 查当月
- NET_DVR_MRD_SEARCH_PARAM struSearchParam = {0};
- NET_DVR_MRD_SEARCH_RESULT struSearchResult = {0};
- struSearchParam.dwSize = sizeof(NET_DVR_MRD_SEARCH_PARAM);
- struSearchParam.wYear = DateNow.year();
- struSearchParam.byMonth = DateNow.month();
- struSearchParam.struStreamInfo.dwChannel = m_Channel; // channel
- struSearchParam.byLocalOrUTC = true; // 0:local time, 1:UTC time (时区)
- struSearchParam.byDrawFrame = 0; // 0:不抽帧,1:抽帧
- struSearchParam.byStreamType = 0;// 0:主码流,1:子码流
- // 查记录
- if (!NET_DVR_GetDeviceConfig(this->LoginID, NET_DVR_GET_MONTHLY_RECORD_DISTRIBUTION, 0, &struSearchParam, sizeof(struSearchParam), NULL, &struSearchResult, sizeof(struSearchResult)))
- {
- int n = NET_DVR_GetLastError();
- return n == NET_DVR_NETWORK_FAIL_CONNECT ? NVR_ERR_CONNECT_7 : NVR_ERR_HIK;
- }
- for (int i = 0; i < 32; i++)
- {
- if (struSearchResult.byRecordDistribution[i])
- {
- available_date_vec.push_back(i + 1);
- }
- }
- return NVR_SUC;
- }
- /**
- * @brief Check if a given time falls within the available time range for the current day.
- *
- * @param select_time The time to check.
- * @param available_time_vec A vector of available time ranges for the current day.
- * @return true if the given time falls within the available time range, false otherwise.
- */
- int HIKNvr::CheckTimeRegionWithDay(DateTime select_time, std::vector<TimeRecord> &available_time_vec)
- {
- int nRet = NVR_SUC;
- GetNvrUTCDiff();
- DateTime DateNow(select_time);
- int nYear = DateNow.year();
- int nMonth = DateNow.month();
- int nDay = DateNow.day();
- NET_DVR_FILECOND FileCond;
- FileCond.dwFileType = 0xff;// 0xff:所有文件
- FileCond.dwIsLocked = 0xff;// 0xff:所有文件
- FileCond.dwUseCardNo = 0; //不使用卡号
- FileCond.lChannel = m_Channel;//通道号
- FileCond.struStartTime.dwYear = DateNow.year();
- FileCond.struStartTime.dwMonth = DateNow.month();
- FileCond.struStartTime.dwDay = DateNow.day();
- FileCond.struStartTime.dwHour = 0;
- FileCond.struStartTime.dwMinute = 0;
- FileCond.struStartTime.dwSecond = 0;
- FileCond.struStopTime.dwYear = DateNow.year();
- FileCond.struStopTime.dwMonth = DateNow.month();
- FileCond.struStopTime.dwDay = DateNow.day();
- FileCond.struStopTime.dwHour = 23;
- FileCond.struStopTime.dwMinute = 59;
- FileCond.struStopTime.dwSecond = 59;
- available_time_vec.clear();
- LONG hFindHandle = NET_DVR_FindFile_V30(LoginID, &FileCond);
- if (-1 == hFindHandle)
- {
- nRet = NET_DVR_GetLastError();
- return nRet == NET_DVR_NETWORK_FAIL_CONNECT?NVR_ERR_CONNECT_7:NVR_ERR_HIK;
- }
- else
- {
- NET_DVR_FINDDATA_V30 FindData; // 查找到的文件信息
- nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
- int ItemIndex = 0;
- while (nRet > 0)
- {
- if (NET_DVR_FILE_EXCEPTION == nRet)//查找文件时异常
- {
- break;
- }
- else if (NET_DVR_FILE_NOFIND == nRet)//没有文件
- {
- break;
- }
- else if (NET_DVR_NOMOREFILE == nRet) // 查找结束
- {
- break;
- }
- else if (NET_DVR_ISFINDING == nRet) // 正在查找
- {
- nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
- //请求过快,会出读错误。同时也是参考海康sdk写法。
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- }
- else if (NET_DVR_FILE_SUCCESS == nRet) // 获取文件信息成功
- {
- // 保存文件信息
- TimeRecord tR;
- if (nDay != FindData.struStartTime.dwDay)//起始不在今日
- {
- tR.TimeStart.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, nDay, 0, 0, 0);
- }
- else//起始在今日
- {
- tR.TimeStart.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, FindData.struStartTime.dwDay, FindData.struStartTime.dwHour, FindData.struStartTime.dwMinute, FindData.struStartTime.dwSecond);
- }
- if (nDay != FindData.struStopTime.dwDay)//结束不在今日
- {
- tR.TimeEnd.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, FindData.struStartTime.dwDay, 23, 59, 59);
- }
- else//结束在今日
- {
- tR.TimeEnd.SetDateTime(FindData.struStopTime.dwYear, FindData.struStopTime.dwMonth, FindData.struStopTime.dwDay,
- FindData.struStopTime.dwHour, FindData.struStopTime.dwMinute, FindData.struStopTime.dwSecond);
- }
- date::sys_days original_date_start{date::year{tR.TimeStart.year()} / date::month{static_cast<unsigned int>(tR.TimeStart.month())} / date::day{static_cast<unsigned int>(tR.TimeStart.day())}};
- date::sys_time<std::chrono::seconds> original_time_start{date::sys_days{original_date_start} + std::chrono::hours{tR.TimeStart.hour()} + std::chrono::minutes{tR.TimeStart.minute()} + std::chrono::seconds{tR.TimeStart.minute()}};
- date::sys_time<std::chrono::seconds> utc_plus_8_time_start = original_time_start - std::chrono::minutes{nDiffTotalMin};
- date::sys_days original_date_end{date::year{tR.TimeEnd.year()} / date::month{static_cast<unsigned int>(tR.TimeEnd.month())} / date::day{static_cast<unsigned int>(tR.TimeEnd.day())}};
- date::sys_time<std::chrono::seconds> original_time_end{date::sys_days{original_date_end} + std::chrono::hours{tR.TimeEnd.hour()} + std::chrono::minutes{tR.TimeEnd.minute()} + std::chrono::seconds{tR.TimeEnd.minute()}};
- date::sys_time<std::chrono::seconds> utc_plus_8_time_end = original_time_end - std::chrono::minutes{nDiffTotalMin};
- // 计算时间点到1970-01-01 00:00:00 UTC的时间间隔,即时间戳
- std::chrono::seconds timestamp = std::chrono::duration_cast<std::chrono::seconds>(utc_plus_8_time_start.time_since_epoch());
- tR.tmTimeStart = timestamp.count();
- timestamp = std::chrono::duration_cast<std::chrono::seconds>(utc_plus_8_time_end.time_since_epoch());
- tR.tmTimeEnd = timestamp.count();
- available_time_vec.emplace_back(tR);
- nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
- }
- }
- // 关闭查找,释放句柄
- NET_DVR_FindClose_V30(hFindHandle);
- }
- return NVR_SUC;
- }
- /**
- * @brief Get the time region based on the selected time and value.
- *
- * @param SelectTime The selected time.
- * @param Value The value used to calculate the time region.
- * @param TimeStart The start time of the time region.
- * @param TimeEnd The end time of the time region.
- * @return true if the time region is found, false otherwise.
- */
- bool HIKNvr::GetTimeRegion(DateTime SelectTime, int Value, DateTime &TimeStart, DateTime &TimeEnd)
- {
- int nYear = SelectTime.year();
- int nMonth = SelectTime.month();
- int nDay = SelectTime.day();
- // 时间格式 转换,找时间区间
- int nHour = Value / 3600;
- int nMinute = Value / 60 - 60 * nHour;
- int nSecond = Value - (nMinute + 60 * nHour) * 60;
- TimeStart = SelectTime;
- TimeStart.hour() = nHour;
- TimeStart.minute() = nMinute;
- TimeStart.second() = nSecond;
- bool bHave = false;
- for (auto it : m_TimeRecords)
- {
- if (it.IsInRecord(TimeStart))
- {
- bHave = true;
- TimeEnd = it.TimeEnd;
- break;
- }
- }
- return bHave;
- }
- /**
- * @brief Turn the time to json.
- *
- * @param Time The time to be turned to json.
- * @param pAvailableDateVec The available date vector.
- * @return nlohmann::json& The json object.
- */
- nlohmann::json HIKNvr::TimeToJson(DateTime Time, std::vector<int> *pAvailableDateVec)
- {
- nlohmann::json Message;
- //year and month
- Message["year"] = Time.year();
- Message["month"] = Time.month();
-
- //date
- if (pAvailableDateVec != nullptr)
- {
- nlohmann::json data;
- for (auto date : *pAvailableDateVec)
- {
- data.push_back(date);
- }
- Message["day"] = data;
- }
- return Message;
- }
- /**
- * @brief Converts available time slots in a day to JSON format.
- *
- * @param Time The date and time of the day.
- * @param pAvailableTimeVec A pointer to a vector of available time slots.
- * @return nlohmann::json& A reference to the JSON object containing the converted time slots.
- */
- nlohmann::json HIKNvr::TimeToJsonInDay(DateTime Time, std::vector<TimeRecord> *pAvailableTimeVec)
- {
- nlohmann::json Message;
- if(pAvailableTimeVec != nullptr)
- {
- for(auto time : *pAvailableTimeVec)
- {
- nlohmann::json data;
- data["begin"] = time.tmTimeStart;
- data["end"] = time.tmTimeEnd;
- Message.push_back(data);
- }
- }
- return Message;
- }
|