You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.3 KiB
174 lines
5.3 KiB
using Cis.Application.Cb;
|
|
using Cis.Application.Cm;
|
|
using Cis.Application.Core.Component.MarkSeacher;
|
|
using Cis.Application.Core.Component.PtzServer;
|
|
using EC.Helper.CameraSDK;
|
|
using StackExchange.Profiling.Internal;
|
|
using StackExchange.Redis;
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace Cis.Application.Core;
|
|
|
|
public class CameraDataCenter : ISingleton
|
|
{
|
|
#region Attr
|
|
|
|
private readonly SqlSugarRepository<CbCamera> _cbCameraRep;
|
|
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
|
|
private readonly IDatabase _cache;
|
|
|
|
private readonly CameraDataOptions _options;
|
|
private readonly ICameraSdkServer _cameraSdkServer;
|
|
private readonly IMarkSearcherServer _markSearcherServer;
|
|
|
|
/// <summary>
|
|
/// {cameraId, List(MarkLabelCalcResult)}
|
|
/// </summary>
|
|
|
|
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> SearchResultListDict { get; set; } = new();
|
|
|
|
#endregion Attr
|
|
|
|
public CameraDataCenter(
|
|
IDatabase cache,
|
|
ICameraSdkServer cameraSdkServer,
|
|
IMarkSearcherServer markSearcherServer
|
|
)
|
|
{
|
|
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>();
|
|
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>();
|
|
_cache = cache;
|
|
_options = App.GetOptions<CameraDataOptions>();
|
|
_cameraSdkServer = cameraSdkServer;
|
|
_markSearcherServer = markSearcherServer;
|
|
InitThread();
|
|
}
|
|
|
|
#region Loop
|
|
|
|
private Thread RefreshCameraPtzThread { get; set; }
|
|
|
|
private Thread RefreshMarkSearcherThread { get; set; }
|
|
|
|
/// <summary>
|
|
/// 初始化线程
|
|
/// </summary>
|
|
private void InitThread()
|
|
{
|
|
// 初始化 CameraPtzThread
|
|
RefreshCameraPtzThread = new Thread(() =>
|
|
{
|
|
while (true)
|
|
{
|
|
RefreshCameraPtzInfos();
|
|
Thread.Sleep(_options.CameraPtz.LoopInterval);
|
|
}
|
|
})
|
|
{
|
|
IsBackground = true// 设置后台线程
|
|
};
|
|
// 启动 CameraPtzThread
|
|
RefreshCameraPtzThread.Start();
|
|
|
|
// 初始化 MarkSearcherThread
|
|
RefreshMarkSearcherThread = new Thread(() =>
|
|
{
|
|
while (true)
|
|
{
|
|
RefreshMarkSearchers();
|
|
Thread.Sleep(_options.MarkSearcher.LoopInterval);
|
|
}
|
|
})
|
|
{
|
|
IsBackground = true// 设置后台线程
|
|
};
|
|
// 启动 MarkSearcherThread
|
|
RefreshMarkSearcherThread.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新所有相机 ptz
|
|
/// 有待改善,应设置超时计数机制
|
|
/// https://blog.csdn.net/qq_28368039/article/details/118597396
|
|
/// </summary>
|
|
private async void RefreshCameraPtzInfos()
|
|
{
|
|
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraIpCounts);
|
|
List<Task> tasks = new();
|
|
foreach (HashEntry entry in entries)
|
|
{
|
|
string cameraIp = entry.Name;
|
|
tasks.Add(RefreshCameraPtzInfo(cameraIp));
|
|
}
|
|
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新相机 ptz
|
|
/// </summary>
|
|
/// <param name="cameraIp"></param>
|
|
/// <returns></returns>
|
|
private async Task RefreshCameraPtzInfo(string cameraIp)
|
|
{
|
|
bool ret = _cameraSdkServer.GetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo);
|
|
if (!ret) return;
|
|
await _cache.HashSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新所有 markSearcher
|
|
/// </summary>
|
|
private async void RefreshMarkSearchers()
|
|
{
|
|
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraId2Ip);
|
|
List<Task> tasks = new();
|
|
foreach (HashEntry entry in entries)
|
|
{
|
|
string cameraId = entry.Name;
|
|
tasks.Add(RefreshMarkSearcher(cameraId.ToLong()));
|
|
}
|
|
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新 markSearcher
|
|
/// </summary>
|
|
/// <param name="cameraId"></param>
|
|
/// <returns></returns>
|
|
private async Task RefreshMarkSearcher(long cameraId)
|
|
{
|
|
MarkSearcherBase markSearcher = _markSearcherServer.GetSearcher(cameraId);
|
|
if (markSearcher == null) return;
|
|
string cameraIp = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId);
|
|
RedisValue value = _cache.HashGet(CacheInfo.CameraPtzInfos, cameraIp);
|
|
if (!value.HasValue) return;
|
|
PtzInfo ptzInfo = value.ToString().FromJson<PtzInfo>();
|
|
markSearcher.UpdateCameraCalcParams(ptzInfo);
|
|
List<MarkLabelCalcResult> resultList = await markSearcher.SearchAsync();
|
|
SearchResultListDict[cameraId] = resultList;
|
|
}
|
|
|
|
#endregion Loop
|
|
|
|
#region Base Method
|
|
|
|
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId)
|
|
{
|
|
bool ret = SearchResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> resultList);
|
|
return ret ? resultList : new List<MarkLabelCalcResult>();
|
|
}
|
|
|
|
#endregion Base Method
|
|
|
|
#region Base Method Async
|
|
|
|
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId)
|
|
{
|
|
return await Task.Run(() =>
|
|
{
|
|
return GetMarkLabelCalcResultList(cameraId);
|
|
});
|
|
}
|
|
|
|
#endregion Base Method Async
|
|
}
|