430 lines
20 KiB
C#
430 lines
20 KiB
C#
//2021年4月14日16点36分 联动的时候不在多次登录NVR,
|
||
using Abp.Dependency;
|
||
using Newtonsoft.Json.Linq;
|
||
using System.Collections.Concurrent;
|
||
using VideoSurveillanceAdapter;
|
||
using Yunda.ISAS.DataMonitoringServer.DataAnalysis.AlarmQueue;
|
||
using Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection;
|
||
using Yunda.ISAS.DataMonitoringServer.DataAnalysis.Helper;
|
||
using Yunda.ISAS.DataMonitoringServer.DataAnalysis.Model;
|
||
using Yunda.ISAS.DataMonitoringServer.DataCenter;
|
||
using YunDa.ISAS.Core.Entity;
|
||
using YunDa.ISAS.DataTransferObject.DataMonitoring.LinkageExecuteActivityDto;
|
||
using YunDa.ISAS.DataTransferObject.VideoSurveillance.PresetPointDto;
|
||
using YunDa.ISAS.Entities.MySQL.DataMonitoring;
|
||
using YunDa.ISAS.ExternalInteraction.DataTransferObject.InspectionEquipment;
|
||
|
||
namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.LinkageAnalysis
|
||
{
|
||
public class ImpletementLinkActives : ISingletonDependency
|
||
{
|
||
private readonly CameraDataCenter _cameraDataCenter;
|
||
private readonly WebApiRequest _webApiRequest;
|
||
private readonly ConfigurationHepler _configurationHepler;
|
||
private readonly RunningDataCache _runningDataCache;
|
||
private readonly TeleCommandDataSendTask _teleCommandDataSendTask;
|
||
private readonly AlarmQueueDataPublish _alarmQueueDataPublish;
|
||
public ImpletementLinkActives(CameraDataCenter cameraDataCenter,
|
||
WebApiRequest webApiRequest,
|
||
ConfigurationHepler configurationHepler,
|
||
RunningDataCache runningDataCache,
|
||
TeleCommandDataSendTask teleCommandDataSendTask,
|
||
AlarmQueueDataPublish alarmQueueDataPublish
|
||
|
||
)
|
||
{
|
||
|
||
_cameraDataCenter = cameraDataCenter;
|
||
_webApiRequest = webApiRequest;
|
||
_configurationHepler = configurationHepler;
|
||
_teleCommandDataSendTask = teleCommandDataSendTask;
|
||
_runningDataCache = runningDataCache;
|
||
_alarmQueueDataPublish = alarmQueueDataPublish;
|
||
}
|
||
private readonly object locker = new object();
|
||
/// <summary>
|
||
/// 执行联动
|
||
/// </summary>
|
||
/// <param name="linkageStrategy"></param>
|
||
public Task ExecuteLinkageDataAsync(LinkageStrategyModel linkageStrategy,
|
||
string reslutStr,
|
||
string code
|
||
)
|
||
{
|
||
List<Guid> cameraActives = new List<Guid>();
|
||
Task rstTask = null;
|
||
ConcurrentDictionary<Guid, List<LinkageExecuteActivityOutput>> _cameraActives
|
||
= new ConcurrentDictionary<Guid, List<LinkageExecuteActivityOutput>>();
|
||
|
||
var req = new LinkageResultInput
|
||
{
|
||
TransformerSubstationId = _configurationHepler.SubstationId,
|
||
LinkageStrategyId = linkageStrategy.Id,
|
||
LinkageStrategyName = linkageStrategy.Name,
|
||
LinkageStartTime = DateTime.Now,
|
||
AlarmLevel = linkageStrategy.DMAlarmCategory == null ? 0 : linkageStrategy.DMAlarmCategory.Level,
|
||
AlarmName = linkageStrategy.DMAlarmCategory?.Name,
|
||
DMAlarmCategoryId = linkageStrategy.DMAlarmCategoryId,
|
||
LinkageEndTime = null,
|
||
Result = reslutStr,
|
||
Status = 0,
|
||
Message = "",
|
||
};
|
||
try
|
||
{
|
||
JObject rstDataJObject = ToolLibrary.HttpHelper.HttpGetRequest<JObject>($"{ConstantModel.RequestLinkageExecuteActivityFindActivityByLinkageIdUri}?linkageId={linkageStrategy.Id}", null);
|
||
var rst = rstDataJObject?["result"]?["resultData"];//获取结果集
|
||
if (rst == null)
|
||
{
|
||
return rstTask;
|
||
}
|
||
var actives = rst.ToObject<List<LinkageExecuteActivityOutput>>();
|
||
var listFiles = new List<AttachmentFile>();
|
||
///当执行活动为摄像机时,需要异步处理
|
||
List<Task> tasks = new List<Task>();
|
||
foreach (var item in actives)
|
||
{
|
||
|
||
|
||
if (item.ActivityType == ActivityTypeEnum.Video)
|
||
{
|
||
if (item?.PresetPoint?.VideoDev == null)
|
||
{
|
||
continue;
|
||
}
|
||
if (_cameraActives.ContainsKey(item.PresetPoint.VideoDev.Id))
|
||
{
|
||
_cameraActives[item.PresetPoint.VideoDev.Id].Add(item);
|
||
}
|
||
else
|
||
{
|
||
while (!_cameraActives.TryAdd(item.PresetPoint.VideoDev.Id, new List<LinkageExecuteActivityOutput>() { item }))
|
||
{
|
||
Task.Delay(10).Wait();
|
||
}
|
||
}
|
||
|
||
}
|
||
else if (item.ActivityType == YunDa.ISAS.Entities.MySQL.DataMonitoring.ActivityTypeEnum.Telecommand) //遥控命令直接执行
|
||
{
|
||
var equipment = _webApiRequest.GetEquipmentInfo((Guid)item.EquipmentInfoId);
|
||
if (equipment != null)
|
||
{
|
||
if (!equipment.IsActive || equipment.SafetyStateType == YunDa.ISAS.Entities.GeneralInformation.SafetyStateTypeEnum.Disarming)
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
/// 执行 发送遥控命令操作
|
||
ImplementTeleCommandAction(item, ref req);
|
||
MonitoringEventBus.LogHandler(req.Message, "联动遥控信息");
|
||
}
|
||
}
|
||
foreach (var item in _cameraActives)
|
||
{
|
||
Task task = Task.Run(() =>
|
||
{
|
||
ExcuteCameraAction(item.Value, ref req, ref listFiles, code);
|
||
});
|
||
tasks.Add(task);
|
||
}
|
||
//bool isPersonInvasion = false;
|
||
if (linkageStrategy.IsPatternRecognize)
|
||
{
|
||
foreach (var item in listFiles)
|
||
{
|
||
var path = Path.GetFullPath("./CaptureJPEGPicture/" + item.FileName);
|
||
if (File.Exists(path))
|
||
{
|
||
var res = _webApiRequest.GetPatternRecongnozeResult(path);
|
||
if (res!="")
|
||
{
|
||
reslutStr += ";图形复核结果:"+ res;
|
||
//isPersonInvasion = true;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
_alarmQueueDataPublish.LinkageAlarmAsync(linkageStrategy, reslutStr, _cameraActives);
|
||
//当动作执行完后进行异步上传文件
|
||
rstTask = Task.WhenAll(tasks.ToArray()).ContinueWith((t) =>
|
||
{
|
||
try
|
||
{
|
||
req.LinkageEndTime = DateTime.Now;
|
||
req.LinkageFiles = listFiles;
|
||
string filePath = _webApiRequest.GetRelativePath(ref req); //获取相对路径
|
||
foreach (var item in listFiles)
|
||
{
|
||
if (item.FileType == AttachmentFileType.Photo)
|
||
{
|
||
var path = Path.GetFullPath("./CaptureJPEGPicture/" + item.FileName);
|
||
if (File.Exists(path))
|
||
{
|
||
string result = _webApiRequest.ResumeFile(ConstantModel.RequestLinkageResultFileUploadUri, path, filePath, 0, 1024 * 128);
|
||
MonitoringEventBus.LogHandler($"{item.FileName}_{result}", "上传联动文件");
|
||
//File.Delete(path);
|
||
}
|
||
}
|
||
else if (item.FileType == AttachmentFileType.Video)
|
||
{
|
||
//var path = Path.GetFullPath("./RecordVideo/" + item.FileName);
|
||
//if (File.Exists(path))
|
||
//{
|
||
// string result = LinkCommuication.Instance.ResumeFile(ConstantModel.RequestLinkageResultFileUploadUri, path, filePath, 0, 1024 * 128);
|
||
// MonitoringEventBus.LogHandler($"{ item.FileName}_{result}", "上传联动文件");
|
||
// File.Delete(path);
|
||
//}
|
||
}
|
||
}
|
||
if (Directory.Exists("./CaptureJPEGPicture/"))
|
||
{
|
||
var files = Directory.GetFiles("./CaptureJPEGPicture/");
|
||
//var delefiles = new List<string>();
|
||
foreach (var file in files)
|
||
{
|
||
if (DateTime.Now - File.GetCreationTime(file) > TimeSpan.FromDays(1))
|
||
{
|
||
File.Delete(file);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MonitoringEventBus.LogHandler(ex.ToString(), "异常信息");
|
||
}
|
||
|
||
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MonitoringEventBus.LogHandler(ex.ToString(), "异常信息");
|
||
}
|
||
return rstTask;
|
||
}
|
||
/// <summary>
|
||
/// 执行摄像机动作
|
||
/// </summary>
|
||
/// <param name="linkageExecuteActivities"></param>
|
||
/// <param name="req"></param>
|
||
/// <param name="listFiles"></param>
|
||
/// <param name="code"></param>
|
||
public void ExcuteCameraAction(List<LinkageExecuteActivityOutput> linkageExecuteActivities,
|
||
ref LinkageResultInput req,
|
||
ref List<AttachmentFile> listFiles,
|
||
string code
|
||
)
|
||
{
|
||
try
|
||
{
|
||
foreach (var linkageExecuteActivity in linkageExecuteActivities)
|
||
{
|
||
if (linkageExecuteActivity.KeepTime == null)
|
||
{
|
||
linkageExecuteActivity.KeepTime = 0;
|
||
}
|
||
var camera = _webApiRequest.GetVideoDevData(linkageExecuteActivity.PresetPointId).Item1;
|
||
if (camera == null)
|
||
{
|
||
break;
|
||
}
|
||
var apply = _webApiRequest.GetApplyControlToExternalstr(camera.Id,
|
||
(int)linkageExecuteActivity.KeepTime, code);
|
||
if (!apply)
|
||
{
|
||
MonitoringEventBus.LogHandler(camera.DevName + "权限获取失败", "摄像头error");
|
||
return;
|
||
}
|
||
var preset = _webApiRequest.GetVideoDevData(linkageExecuteActivity.PresetPointId).Item2;
|
||
var nvr = camera.Parent;
|
||
CameraBrand cb = CameraBrand.None;
|
||
Enum.TryParse(nvr.ManufacturerInfo.ManufacturerCode, out cb);
|
||
if (cb == CameraBrand.None)
|
||
{
|
||
MonitoringEventBus.LogHandler("[" + nvr.DevName + "]NVR厂商品牌不正确!", "摄像头error");
|
||
return;
|
||
}
|
||
|
||
VideoPlayer videoPlayer = new VideoPlayer();
|
||
videoPlayer.CameraConfigure = new CameraConfigure
|
||
{
|
||
ID = nvr.Id.ToString(),
|
||
Name = nvr.DevName,
|
||
Ip = nvr.IP,
|
||
Port = (int)nvr.Port,
|
||
UserName = nvr.DevUserName,
|
||
Password = nvr.DevPassword,
|
||
IsRecordVideo = false,
|
||
//VideoPath = @".\Video\",
|
||
//CapturePath = @".\Capture\",
|
||
CameraBrand = cb,
|
||
//PlayChannel = Convert.ToInt32(camera.ChannelNo)
|
||
};
|
||
|
||
try
|
||
{
|
||
|
||
|
||
var player = _cameraDataCenter.FindCamera(videoPlayer);
|
||
if (player == null)
|
||
{
|
||
var isloginSuccess = videoPlayer.LoginCamera();
|
||
if (isloginSuccess)
|
||
{
|
||
_cameraDataCenter.CameraCollection.Add(videoPlayer);
|
||
}
|
||
else
|
||
{
|
||
MonitoringEventBus.LogHandler($"{videoPlayer.CameraConfigure.Name}登陆失败", "异常信息");
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
videoPlayer = player;
|
||
}
|
||
bool isSccess = videoPlayer.GotoPreset(preset.Number, Convert.ToInt32(camera.ChannelNo)); ///转到预置位 枪机不同的型号表现不同,这里采用不管转预置位的成功与否
|
||
|
||
//是否拍照
|
||
if (linkageExecuteActivity.IsCapturePicture)
|
||
{
|
||
Task.Delay(linkageExecuteActivity.KeepTime.HasValue ? (int)linkageExecuteActivity.KeepTime * 1000 : 0).Wait();
|
||
// 执行拍照动作
|
||
var req1 = new ApplyControlToExternalInput()
|
||
{
|
||
Code = code,
|
||
CamNames = new List<string>() { camera.DevName }
|
||
};
|
||
_webApiRequest.SendFreeCamAuth(req1);
|
||
var res = LinkActivesCaptureJPEGPicture(videoPlayer, camera, preset, ref listFiles);
|
||
//if (camera.IsInfraredCamera)
|
||
//{
|
||
// var res = LinkActivesCaptureJPEGPicture(videoPlayer, camera, preset, ref listFiles);
|
||
// var filePath = res.Item2;
|
||
// if (res.Item1) //拍照成功
|
||
// {
|
||
// //根据预置点查找测温点信息
|
||
// List<MeasureTemperaturePoint> mesurePonitInfos = _webApiRequest.GetMeasurePointInfoByPresetPointId(preset.Id);
|
||
// DrawMeasurePointInfo(mesurePonitInfos, ref filePath);
|
||
// }
|
||
//}
|
||
//else
|
||
//{
|
||
// var res = LinkActivesCaptureJPEGPicture(videoPlayer, camera, preset, ref listFiles);
|
||
|
||
//}
|
||
}
|
||
//是否录像
|
||
if (linkageExecuteActivity.IsRecordVideo)
|
||
{
|
||
//var res = LinkActivesRecordVideoAsync(videoPlayer, camera, preset, linkageExecuteActivity.RecordDuration).GetAwaiter().GetResult();
|
||
//if (res.Item1)
|
||
//{
|
||
// req.Message += $"相机:{camera.DevName}\r\n预置点:{preset.Name}\r\n结果信息:录像成功\r\n";
|
||
// if (res.Item3 != null)
|
||
// listFiles.AddRange(res.Item3);
|
||
//}
|
||
//else
|
||
//{
|
||
// req.Message += $"相机:{camera.DevName}\r\n预置点:{preset.Name}\r\n结果信息:录像失败\r\n";
|
||
//}
|
||
}
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MonitoringEventBus.LogHandler(ex.ToString(), "摄像头error");
|
||
}
|
||
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MonitoringEventBus.LogHandler(ex.ToString(), "异常信息");
|
||
}
|
||
|
||
|
||
}
|
||
|
||
//private void DrawMeasurePointInfo(List<MeasureTemperaturePoint> mesurePonitInfos, ref string filePath)
|
||
//{
|
||
// foreach (var mesurePonitInfo in mesurePonitInfos)
|
||
// {
|
||
// var tmpValue = _webApiRequest.GetMeasurePointNearestValue((Guid)mesurePonitInfo.PresetPointId, mesurePonitInfo.Number);
|
||
// List<MeasureTempCoordinate> measureTempCoordinates = JsonConvert.DeserializeObject<List<MeasureTempCoordinate>>(mesurePonitInfo.CoordinateJsonStr);
|
||
// if (measureTempCoordinates != null && measureTempCoordinates.Count > 0)
|
||
// {
|
||
// SkiaSharpHandlePicture skiaSharpHandlePicture = new SkiaSharpHandlePicture();
|
||
// //温度值采用四舍五入的方式保留两位小数
|
||
// //绘图
|
||
// //返回的文件路径作为下次绘图的底图
|
||
// skiaSharpHandlePicture.Bitmap(measureTempCoordinates, ref filePath, $"{mesurePonitInfo.Name}:{ Math.Round(tmpValue, 2)}℃");
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 截图
|
||
/// </summary>
|
||
/// <param name="videoPlayer"></param>
|
||
/// <param name="camera"></param>
|
||
/// <param name="preset"></param>
|
||
private (bool, string) LinkActivesCaptureJPEGPicture(VideoPlayer videoPlayer, VideoDev camera,
|
||
PresetPointProperty preset, ref List<AttachmentFile> listFiles)
|
||
{
|
||
if (!Directory.Exists("./CaptureJPEGPicture"))
|
||
{
|
||
Directory.CreateDirectory("./CaptureJPEGPicture");
|
||
}
|
||
var name = $"{camera.DevName}_{preset.Name}_{DateTime.Now.ToString("HHmmss")}_{Guid.NewGuid().ToString()}.jpg";
|
||
var fileName = $"./CaptureJPEGPicture/{name}";
|
||
var filePath = Path.GetFullPath(fileName);
|
||
var res = videoPlayer.CaptureJPEGPicture(filePath, Convert.ToInt32(camera.ChannelNo));
|
||
if (res)
|
||
{
|
||
listFiles.Add(new AttachmentFile
|
||
{
|
||
FileExtension = ".jpg",
|
||
FileName = name,
|
||
FileType = AttachmentFileType.Photo
|
||
});
|
||
}
|
||
return (res, filePath);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 执行遥控联动
|
||
/// </summary>
|
||
/// <param name="item"></param>
|
||
public void ImplementTeleCommandAction(LinkageExecuteActivityOutput item, ref LinkageResultInput req)
|
||
{
|
||
try
|
||
{
|
||
var telecommand = _runningDataCache.TelecommandModels.FirstOrDefault(t => t.Id == item.TelecommandConfigurationId);
|
||
if (telecommand != null)
|
||
{
|
||
telecommand.CommandValue = item.TelecommandValue;
|
||
telecommand.Source = "服务联动";
|
||
telecommand.Sender = telecommand.Name;
|
||
//发送给104装置
|
||
_teleCommandDataSendTask.TelecommandTActionBlock.Post(new DataCollection.TelcommandDataModel()
|
||
{
|
||
Telecommand = telecommand
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MonitoringEventBus.LogHandler(ex.ToString(), "异常信息");
|
||
}
|
||
|
||
}
|
||
}
|
||
} |