133 lines
4.8 KiB
C#
133 lines
4.8 KiB
C#
|
|
using System.ComponentModel;
|
|||
|
|
using System.Runtime.CompilerServices;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Input;
|
|||
|
|
|
|||
|
|
namespace SHH.CameraDashboard
|
|||
|
|
{
|
|||
|
|
public class CameraPtzViewModel : INotifyPropertyChanged
|
|||
|
|
{
|
|||
|
|
private readonly WebApiCameraModel _camera;
|
|||
|
|
|
|||
|
|
public string Title => $"{_camera.Name} - 云台控制";
|
|||
|
|
|
|||
|
|
public ICommand StartCommand { get; }
|
|||
|
|
public ICommand StopCommand { get; }
|
|||
|
|
|
|||
|
|
// 用于关闭面板
|
|||
|
|
public ICommand CloseCommand { get; }
|
|||
|
|
|
|||
|
|
public ICommand SyncTimeCommand { get; }
|
|||
|
|
public ICommand RebootCommand { get; }
|
|||
|
|
|
|||
|
|
// ★★★ [新增] 关闭请求事件,通知 MainViewModel 关闭面板
|
|||
|
|
public event Action? RequestClose;
|
|||
|
|
|
|||
|
|
public CameraPtzViewModel(WebApiCameraModel camera)
|
|||
|
|
{
|
|||
|
|
_camera = camera;
|
|||
|
|
|
|||
|
|
// 使用非泛型 RelayCommand,但在 Execute 中强转参数
|
|||
|
|
StartCommand = new RelayCommand(ExecuteStart);
|
|||
|
|
StopCommand = new RelayCommand(ExecuteStop);
|
|||
|
|
|
|||
|
|
// 关闭逻辑:可以简单地请求刷新或置空 MainVM 的属性(这里暂用刷新模拟)
|
|||
|
|
CloseCommand = new RelayCommand(o => RequestClose?.Invoke());
|
|||
|
|
|
|||
|
|
// [新增] 初始化运维命令
|
|||
|
|
SyncTimeCommand = new RelayCommand(ExecuteSyncTime);
|
|||
|
|
RebootCommand = new RelayCommand(ExecuteReboot);
|
|||
|
|
}
|
|||
|
|
// [新增] 执行校时
|
|||
|
|
private async void ExecuteSyncTime(object obj)
|
|||
|
|
{
|
|||
|
|
if (_camera == null) return;
|
|||
|
|
|
|||
|
|
// 可以加个 IsBusy 状态防止连点
|
|||
|
|
bool success = await ApiClient.Instance.Cameras.SyncTimeAsync(_camera.Id);
|
|||
|
|
|
|||
|
|
if (success)
|
|||
|
|
MessageBox.Show("校时指令已发送成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|||
|
|
else
|
|||
|
|
MessageBox.Show("校时失败,请检查网络或日志。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// [新增] 执行重启
|
|||
|
|
private async void ExecuteReboot(object obj)
|
|||
|
|
{
|
|||
|
|
if (_camera == null) return;
|
|||
|
|
|
|||
|
|
// 重启是高风险操作,必须弹窗确认
|
|||
|
|
var result = MessageBox.Show(
|
|||
|
|
$"确定要重启设备 \"{_camera.Name}\" 吗?\n\n注意:\n1. 设备将断开连接约 60 秒。\n2. 录像可能会中断。",
|
|||
|
|
"确认重启",
|
|||
|
|
MessageBoxButton.YesNo,
|
|||
|
|
MessageBoxImage.Warning);
|
|||
|
|
|
|||
|
|
if (result != MessageBoxResult.Yes) return;
|
|||
|
|
|
|||
|
|
bool success = await ApiClient.Instance.Cameras.RebootCameraAsync(_camera.Id);
|
|||
|
|
|
|||
|
|
if (success)
|
|||
|
|
MessageBox.Show("重启指令已发送,设备正在重启中...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|||
|
|
else
|
|||
|
|
MessageBox.Show("重启指令发送失败。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async void ExecuteStart(object parameter)
|
|||
|
|
{
|
|||
|
|
if (parameter is PtzAction action)
|
|||
|
|
{
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"PTZ START: {action}");
|
|||
|
|
|
|||
|
|
// 模式 A: 雨刷 (Wiper) -> 点动模式 (持续 5秒)
|
|||
|
|
if (action == PtzAction.Wiper)
|
|||
|
|
{
|
|||
|
|
await SendPtzRequest(new PtzControlDto
|
|||
|
|
{
|
|||
|
|
Action = action,
|
|||
|
|
Duration = 5000
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 模式 B: 持续动作 (Up/Down/Zoom...) -> Start
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
await SendPtzRequest(new PtzControlDto
|
|||
|
|
{
|
|||
|
|
Action = action,
|
|||
|
|
Stop = false,
|
|||
|
|
Speed = 5
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async void ExecuteStop(object parameter)
|
|||
|
|
{
|
|||
|
|
if (parameter is PtzAction action)
|
|||
|
|
{
|
|||
|
|
// 雨刷是自动复位的,不需要发停止
|
|||
|
|
if (action == PtzAction.Wiper) return;
|
|||
|
|
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"PTZ STOP: {action}");
|
|||
|
|
|
|||
|
|
// 发送停止指令:Action=动作名, Stop=true
|
|||
|
|
await SendPtzRequest(new PtzControlDto
|
|||
|
|
{
|
|||
|
|
Action = action,
|
|||
|
|
Stop = true
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task SendPtzRequest(PtzControlDto payload)
|
|||
|
|
{
|
|||
|
|
if (_camera == null) return;
|
|||
|
|
await ApiClient.Instance.Cameras.PtzControlAsync(_camera.Id, payload);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|||
|
|
protected void OnPropertyChanged([CallerMemberName] string name = null)
|
|||
|
|
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
|||
|
|
}
|
|||
|
|
}
|