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.
405 lines
14 KiB
405 lines
14 KiB
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Threading;
|
|
using EC.Util.CameraSDK;
|
|
using EC.Util.Common;
|
|
using EC.Util.Port;
|
|
using JiLinApp.Biz.TransmitAlarm;
|
|
using JiLinApp.Components;
|
|
using JiLinApp.Core;
|
|
using JiLinApp.Core.App;
|
|
using JiLinApp.Core.Avalonia;
|
|
using JiLinApp.Docking.FenceAlarm;
|
|
using JiLinApp.Docking.Military;
|
|
using JiLinApp.Docking.Ptz;
|
|
using JiLinApp.Docking.VibrateAlarm;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
|
|
namespace JiLinApp.Pages.PtzServer;
|
|
|
|
public partial class Ptz : UserControl
|
|
{
|
|
#region Fields
|
|
|
|
private AppConfig AppConfig { get; } = Global.AppConfig;
|
|
|
|
private MilitaryService MilitaryService { get; } = Global.MilitaryService;
|
|
|
|
private List<CameraLinkageInfo> CameraLinkageList { get; set; } = new();
|
|
|
|
private ConcurrentDictionary<string, ICameraSdk> CameraSdkDict { get; } = new();
|
|
|
|
private ConcurrentDictionary<string, CameraRealPlay> RealPlayDict { get; } = new();
|
|
|
|
private Window? _win;
|
|
|
|
private Window? Wdw
|
|
{
|
|
get
|
|
{
|
|
_win ??= ControlsUtil.GetWindow(this);
|
|
return _win;
|
|
}
|
|
}
|
|
|
|
#endregion Fields
|
|
|
|
public Ptz()
|
|
{
|
|
InitializeComponent();
|
|
|
|
//绑定串口服务开关响应事件
|
|
OpenComBtn.Click += OpenComBtn_Click;
|
|
CloseComBtn.Click += CloseComBtn_Click;
|
|
//绑定实时视频响应事件
|
|
ShowLiveVideoBtn.Click += ShowLiveVideoBtn_Click;
|
|
//绑定云台响应事件
|
|
List<Button> btnList = new();
|
|
ControlsUtil.FindChild(PtzCtrlPanel, ref btnList);
|
|
foreach (var btn in btnList)
|
|
{
|
|
btn.AddHandler(PointerPressedEvent, PtzBtn_MouseDown, RoutingStrategies.Tunnel);
|
|
btn.AddHandler(PointerReleasedEvent, PtzBtn_MouseUp, RoutingStrategies.Tunnel);
|
|
}
|
|
GotoBtn.Click += GotoBtn_Click;
|
|
//绑定云台控制类型更改事件
|
|
ControlTypeNameCbx.SelectionChanged += ControlTypeName_SelectionChanged;
|
|
|
|
MessageEvent.VibrateAlarm.Subscribe(HandleVibrateAlarm);
|
|
MessageEvent.FenceAlarm.Subscribe(HandleFenceAlarm);
|
|
|
|
// 初始化串口下拉框
|
|
string[] ports = SerialPort.GetPortNames().OrderBy(s => int.Parse(Regex.Match(s, @"\d+").Value)).ToArray();
|
|
foreach (string port in ports) ComNameCbx.Items.Add(new ComboBoxItem { Content = port });
|
|
ComNameCbx.SelectedIndex = 0;
|
|
// 初始化相机 sdk 和相机 ip 下拉框
|
|
CameraLinkageList = MilitaryService.GetCameraLinkageList();
|
|
TaskUtil.RunCatch(() => Dispatcher.UIThread.Invoke(() => LoadCameraSdkDict(MilitaryService.GetCameraList())));
|
|
// 初始化云台控制类型下拉框
|
|
foreach (var cfg in AppConfig.Base.PtzCtrlTypes) ControlTypeNameCbx.Items.Add(new ComboBoxItem { Content = cfg.Name });
|
|
ControlTypeNameCbx.SelectedIndex = 0;
|
|
// 初始化相机 id 下拉框
|
|
for (int i = 1; i <= 5; i++) CameraIdCbx.Items.Add(new ComboBoxItem { Content = i });
|
|
CameraIdCbx.SelectedIndex = 0;
|
|
// 初始化预置点 id 下拉框
|
|
for (int i = 1; i <= 10; i++) PresetIdCbx.Items.Add(new ComboBoxItem { Content = i });
|
|
PresetIdCbx.SelectedIndex = 0;
|
|
}
|
|
|
|
#region Com
|
|
|
|
private YcSerialPort? Port { get; set; }
|
|
|
|
private bool IsComConnect()
|
|
{
|
|
return Port != null && Port.IsOpen();
|
|
}
|
|
|
|
private void ChangeState(bool openState)
|
|
{
|
|
OpenComBtn.IsEnabled = !openState;
|
|
CloseComBtn.IsEnabled = openState;
|
|
}
|
|
|
|
#endregion Com
|
|
|
|
#region Element Event
|
|
|
|
private void OpenComBtn_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
if (IsComConnect()) return;
|
|
try
|
|
{
|
|
SerialPortParam param = new()
|
|
{
|
|
ComName = ComNameCbx.GetText(),
|
|
BaudRate = int.Parse(BaudRateCbx.GetText()),
|
|
Parity = 0,
|
|
DataBits = int.Parse(DataBitsCbx.GetText()),
|
|
StopBits = int.Parse(StopBitsCbx.GetText()),
|
|
};
|
|
Port = new YcSerialPort(param);
|
|
Port.OpenCom();
|
|
ChangeState(true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Port = null;
|
|
_ = ControlsUtil.ShowWarnDialog(Wdw, message: ex.ToString());
|
|
LogUnit.Error(ex);
|
|
}
|
|
}
|
|
|
|
private void CloseComBtn_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
if (!IsComConnect()) return;
|
|
try
|
|
{
|
|
Port?.CloseCom();
|
|
Port = null;
|
|
ChangeState(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = ControlsUtil.ShowWarnDialog(Wdw, message: ex.ToString());
|
|
LogUnit.Error(ex);
|
|
}
|
|
}
|
|
|
|
private void PtzBtn_MouseDown(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (sender is not Button btn) return;
|
|
PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ControlTypeNameCbx.GetText());
|
|
PtzCmdType cmdType = PtzCmd.GetCmdType((btn.Name ?? string.Empty).Replace("Btn", ""));
|
|
switch (ctrlType)
|
|
{
|
|
case PtzControlType.PelcoD:
|
|
case PtzControlType.PelcoP:
|
|
if (!IsComConnect()) break;
|
|
byte cameraId = byte.Parse(CameraIdCbx.GetText());
|
|
byte[] cmd = PtzComCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId });
|
|
if (cmd != null && cmd.Length > 0) Port?.SendHex(cmd);
|
|
break;
|
|
|
|
case PtzControlType.DCamera:
|
|
if (!IsComConnect()) break;
|
|
cmd = PtzComCmd.GetCmd(ctrlType, cmdType);
|
|
if (cmd != null && cmd.Length > 0) Port?.SendHex(cmd);
|
|
break;
|
|
|
|
case PtzControlType.CameraSdk:
|
|
string cameraIp = CameraIpCbx.GetText();
|
|
CameraSdkDict.TryGetValue(cameraIp, out ICameraSdk? cameraSdk);
|
|
if (cameraSdk == null) break;
|
|
int stop = 0;
|
|
PtzCameraCmd.PtzMove(cameraSdk, cmdType, new int[] { stop });
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
private void PtzBtn_MouseUp(object? sender, PointerReleasedEventArgs e)
|
|
{
|
|
if (sender is not Button btn) return;
|
|
PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ControlTypeNameCbx.GetText());
|
|
PtzCmdType cmdType = PtzCmdType.Stop;
|
|
switch (ctrlType)
|
|
{
|
|
case PtzControlType.PelcoD:
|
|
case PtzControlType.PelcoP:
|
|
if (!IsComConnect()) break;
|
|
byte cameraId = byte.Parse(CameraIdCbx.GetText());
|
|
byte[] cmd = PtzComCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId });
|
|
if (cmd != null && cmd.Length > 0) Port?.SendHex(cmd);
|
|
break;
|
|
|
|
case PtzControlType.DCamera:
|
|
if (!IsComConnect()) break;
|
|
cmd = PtzComCmd.GetCmd(ctrlType, cmdType);
|
|
if (cmd != null && cmd.Length > 0) Port?.SendHex(cmd);
|
|
break;
|
|
|
|
case PtzControlType.CameraSdk:
|
|
string cameraIp = CameraIpCbx.GetText();
|
|
CameraSdkDict.TryGetValue(cameraIp, out ICameraSdk? cameraSdk);
|
|
if (cameraSdk == null) break;
|
|
cmdType = PtzCmd.GetCmdType((btn.Name ?? string.Empty).Replace("Btn", ""));
|
|
int stop = 1;
|
|
PtzCameraCmd.PtzMove(cameraSdk, cmdType, new int[] { stop });
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
private void GotoBtn_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ControlTypeNameCbx.GetText());
|
|
PtzCmdType cmdType = PtzCmdType.PresetGoto;
|
|
byte presetId = byte.Parse(PresetIdCbx.GetText());
|
|
switch (ctrlType)
|
|
{
|
|
case PtzControlType.PelcoD:
|
|
case PtzControlType.PelcoP:
|
|
if (!IsComConnect()) break;
|
|
byte cameraId = byte.Parse(CameraIdCbx.GetText());
|
|
byte[] cmd = PtzComCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId, presetId });
|
|
if (cmd != null && cmd.Length > 0) Port?.SendHex(cmd);
|
|
break;
|
|
|
|
case PtzControlType.CameraSdk:
|
|
string cameraIp = CameraIpCbx.GetText();
|
|
CameraSdkDict.TryGetValue(cameraIp, out ICameraSdk? cameraSdk);
|
|
if (cameraSdk == null) break;
|
|
PtzCameraCmd.PtzMove(cameraSdk, cmdType, new int[] { presetId });
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
private void ShowLiveVideoBtn_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
string cameraIp = CameraIpCbx.GetText();
|
|
if (!CameraSdkDict.TryGetValue(cameraIp, out ICameraSdk? sdk)) return;
|
|
Dispatcher.UIThread.Invoke(() => ShowLiveVideo(sdk));
|
|
}
|
|
|
|
private void ControlTypeName_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
|
{
|
|
if (e.AddedItems[0] is not ComboBoxItem cbxItem) return;
|
|
string ctrlTypeName = cbxItem?.Content?.ToString() ?? string.Empty;
|
|
PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ctrlTypeName);
|
|
switch (ctrlType)
|
|
{
|
|
case PtzControlType.PelcoD:
|
|
case PtzControlType.PelcoP:
|
|
case PtzControlType.DCamera:
|
|
CameraIdCbx.IsEnabled = true;
|
|
CameraIpCbx.IsEnabled = false;
|
|
ShowLiveVideoBtn.IsEnabled = false;
|
|
break;
|
|
|
|
case PtzControlType.CameraSdk:
|
|
CameraIdCbx.IsEnabled = false;
|
|
CameraIpCbx.IsEnabled = true;
|
|
ShowLiveVideoBtn.IsEnabled = true;
|
|
break;
|
|
|
|
default:
|
|
CameraIdCbx.IsEnabled = false;
|
|
CameraIpCbx.IsEnabled = false;
|
|
ShowLiveVideoBtn.IsEnabled = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion Element Event
|
|
|
|
#region Invoke Event
|
|
|
|
private void ShowLiveVideo(ICameraSdk sdk)
|
|
{
|
|
if (!sdk.ConnectSuccess()) { LogUnit.Error(this, $"CameraSdk(cameraIp:{sdk.CameraInfo.Ip}) connect failure."); return; }
|
|
if (!ControlsUtil.TryGetWindow(this, out Window? w)) return;
|
|
string cameraIp = sdk.CameraInfo.Ip;
|
|
RealPlayDict.TryGetValue(cameraIp, out CameraRealPlay? realPlay);
|
|
if (realPlay == null || realPlay.IsClosed)
|
|
{
|
|
realPlay = new(sdk)
|
|
{
|
|
Title = $"RealPlay({sdk.CameraInfo.Name})",
|
|
CanResize = false,
|
|
ShowInTaskbar = true
|
|
};
|
|
RealPlayDict[cameraIp] = realPlay;
|
|
}
|
|
realPlay.Show(w);
|
|
realPlay.WindowState = WindowState.Normal;
|
|
realPlay.StartPlay();
|
|
}
|
|
|
|
private void HandleVibrateAlarm(TcpAlarmHostMessage msg)
|
|
{
|
|
AlarmMessage alarm = msg.ToAlarmMessage();
|
|
TaskUtil.RunCatch(() => HandleAlarmInvoke(alarm));
|
|
}
|
|
|
|
private void HandleFenceAlarm(UdpAlarmHostMessage msg)
|
|
{
|
|
AlarmMessage alarm = msg.ToAlarmMessage();
|
|
TaskUtil.RunCatch(() => HandleAlarmInvoke(alarm));
|
|
}
|
|
|
|
private void HandleAlarmInvoke(AlarmMessage alarm)
|
|
{
|
|
if (alarm == null) return;
|
|
bool realPlay = AppConfig.AlarmPlatform.RealPlay;
|
|
string deviceId = alarm.LabelCode;
|
|
string sensorId = alarm.ChannelId;
|
|
List<CameraLinkageInfo> cameraLinkages = GetCameraLinkageList(sensorId);
|
|
foreach (var item in cameraLinkages)
|
|
{
|
|
if (item == null) { LogUnit.Error(this, $"CameraLinkageInfo(sensorId:{sensorId}) not found."); return; }
|
|
string cameraId = item.CameraId;
|
|
ICameraSdk? cameraSdk = GetCameraSdk(cameraId);
|
|
if (cameraSdk == null) { LogUnit.Error(this, $"CameraSdk(cameraId:{cameraId}) not found."); return; }
|
|
if (realPlay) Dispatcher.UIThread.Invoke(() => ShowLiveVideo(cameraSdk));
|
|
// TODO: 设计 PriorityQueue
|
|
int len = item.PresetIds.Length;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
int presetId = item.PresetIds[i];
|
|
PtzCameraCmd.PtzMove(cameraSdk, PtzCmdType.PresetGoto, new int[] { presetId });
|
|
if (i != len) Thread.Sleep(5000);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Invoke Event
|
|
|
|
#region Military
|
|
|
|
private void LoadCameraSdkDict(List<CameraInfo> cameraList)
|
|
{
|
|
int tryTime = 5, tryInterval = 500;
|
|
for (int i = 0; i < cameraList.Count; i++)
|
|
{
|
|
CameraInfo info = cameraList[i];
|
|
string ip = info.Ip;
|
|
if (CameraSdkDict.ContainsKey(ip)) continue;
|
|
ICameraSdk sdk = CameraFactory.BuildCameraSdk(info);
|
|
CameraSdkDict[ip] = sdk;
|
|
CameraIpCbx.Items.Add(new ComboBoxItem { Content = ip });
|
|
TaskUtil.RunCatch(() =>
|
|
{
|
|
bool flag = false;
|
|
for (int i = 0; i < tryTime; i++)
|
|
{
|
|
flag = sdk.Init();
|
|
if (flag) break;
|
|
Thread.Sleep(tryInterval);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private CameraLinkageInfo? GetCameraLinkage(string sensorId)
|
|
{
|
|
foreach (var item in CameraLinkageList)
|
|
{
|
|
if (sensorId.Equals(item.SensorId)) return item;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private List<CameraLinkageInfo> GetCameraLinkageList(string sensorId)
|
|
{
|
|
List<CameraLinkageInfo> list = new();
|
|
foreach (var item in CameraLinkageList)
|
|
{
|
|
if (sensorId.Equals(item.SensorId)) list.Add(item);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
private ICameraSdk? GetCameraSdk(string cameraId)
|
|
{
|
|
foreach (var item in CameraSdkDict.Values)
|
|
{
|
|
if (item == null) continue;
|
|
if (cameraId.Equals(item.CameraInfo.Id)) return item;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
#endregion Military
|
|
}
|