|
|
@@ -9,9 +9,13 @@ using Prism.Services.Dialogs;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.ObjectModel;
|
|
|
+using System.Drawing;
|
|
|
using System.Linq;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Channels;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Windows;
|
|
|
+using System.Windows.Threading;
|
|
|
using Team.FFFeederService.Interfaces;
|
|
|
using TeamAAS_VP;
|
|
|
using TeamAAS_VP.Controls;
|
|
|
@@ -21,7 +25,9 @@ using TeamAAS_VP.Enums;
|
|
|
using TeamAAS_VP.Events;
|
|
|
using TeamAAS_VP.Interfaces;
|
|
|
using TeamAAS_VP.Models;
|
|
|
+using TeamAAS_VP.Models.Lights;
|
|
|
using TeamAAS_VP.Resources.Languages;
|
|
|
+using TeamAAS_VP.Services;
|
|
|
using static NPOI.HSSF.Util.HSSFColor;
|
|
|
|
|
|
namespace TeamAAS_VP.ViewModels.Product
|
|
|
@@ -39,6 +45,11 @@ namespace TeamAAS_VP.ViewModels.Product
|
|
|
IProductService _productService;
|
|
|
IRemoteCommandService _remoteCommandService;
|
|
|
ISystemDatabaseService _systemDatabaseService;
|
|
|
+ ILightManagerService _lightManagerService;
|
|
|
+
|
|
|
+ // 创建Channel
|
|
|
+ private readonly Channel<(int channel, int brightness)> _brightnessChannel;
|
|
|
+ private CancellationTokenSource _cancellationTokenSource;
|
|
|
|
|
|
#region 属性
|
|
|
|
|
|
@@ -200,6 +211,18 @@ namespace TeamAAS_VP.ViewModels.Product
|
|
|
public DelegateCommand LightValueSubCommand =>
|
|
|
_LightValueSubCommand ?? (_LightValueSubCommand = new DelegateCommand(ExecuteLightValueSubCommand));
|
|
|
|
|
|
+ private DelegateCommand<object> _SetChannelBrightnessCommand;
|
|
|
+ public DelegateCommand<object> SetChannelBrightnessCommand =>
|
|
|
+ _SetChannelBrightnessCommand ?? (_SetChannelBrightnessCommand = new DelegateCommand<object>(ExecuteSetChannelBrightnessCommand));
|
|
|
+
|
|
|
+ private DelegateCommand<object> _TurnOnCommand;
|
|
|
+ public DelegateCommand<object> TurnOnCommand =>
|
|
|
+ _TurnOnCommand ?? (_TurnOnCommand = new DelegateCommand<object>(ExecuteTurnOnCommand));
|
|
|
+
|
|
|
+ private DelegateCommand<object> _TurnOffCommand;
|
|
|
+ public DelegateCommand<object> TurnOffCommand =>
|
|
|
+ _TurnOffCommand ?? (_TurnOffCommand = new DelegateCommand<object>(ExecuteTurnOffCommand));
|
|
|
+
|
|
|
#endregion
|
|
|
|
|
|
#region 事件
|
|
|
@@ -208,7 +231,7 @@ namespace TeamAAS_VP.ViewModels.Product
|
|
|
|
|
|
public CameraParamsViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService,
|
|
|
IConfigService configService, IRobotService robotService, ICameraService cameraService, IFeederService feederService, IProductService productService,
|
|
|
- IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService)
|
|
|
+ IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService)
|
|
|
{
|
|
|
_regionManager = regionManager;
|
|
|
_eventAggregator = ea;
|
|
|
@@ -223,10 +246,55 @@ namespace TeamAAS_VP.ViewModels.Product
|
|
|
_eventAggregator.GetEvent<UserLoginNotification>().Subscribe(LoginChange);
|
|
|
_productService = productService;
|
|
|
_remoteCommandService = remoteCommandService;
|
|
|
+ _lightManagerService = lightManagerService;
|
|
|
+
|
|
|
+ // 创建有界Channel,容量为1,只保留最新的亮度值
|
|
|
+ _brightnessChannel = Channel.CreateBounded<(int channel, int brightness)>(
|
|
|
+ new BoundedChannelOptions(1) // 容量为1
|
|
|
+ {
|
|
|
+ // 当Channel满时,丢弃最旧的值,写入新的值
|
|
|
+ FullMode = BoundedChannelFullMode.DropOldest,
|
|
|
+
|
|
|
+ // 允许多个UI线程写入(虽然通常只有一个)
|
|
|
+ SingleWriter = false,
|
|
|
+
|
|
|
+ // 只有一个消费者读取并发送到设备
|
|
|
+ SingleReader = true
|
|
|
+ });
|
|
|
+
|
|
|
+ _cancellationTokenSource = new CancellationTokenSource();
|
|
|
+
|
|
|
+ // 启动消费者任务
|
|
|
+ StartDeviceConsumer();
|
|
|
+
|
|
|
}
|
|
|
|
|
|
#region 方法
|
|
|
|
|
|
+ // 消费者:从Channel读取并发送到设备
|
|
|
+ private async void StartDeviceConsumer()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await _brightnessChannel.Reader.WaitToReadAsync(_cancellationTokenSource.Token))
|
|
|
+ {
|
|
|
+ while (_brightnessChannel.Reader.TryRead(out var obj))
|
|
|
+ {
|
|
|
+ // 实际写入(底层方法可能不支持取消)
|
|
|
+ var success = await _lightManagerService.SetGlobalChannelBrightnessAsync(obj.channel, obj.brightness);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (OperationCanceledException)
|
|
|
+ {
|
|
|
+ // 正常结束
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ _brightnessChannel.Writer.Complete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 下一步
|
|
|
/// </summary>
|
|
|
@@ -330,6 +398,75 @@ namespace TeamAAS_VP.ViewModels.Product
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 为指定通道应用亮度设置(仅更新模型并在可能时尝试通知硬件)。
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="channel">要设置的通道配置。</param>
|
|
|
+ async void ExecuteSetChannelBrightnessCommand(object obj)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!(obj is Tuple<object, double, double> parameter)) return;
|
|
|
+
|
|
|
+ if (!(parameter.Item1 is ChannelConfig channel)) return;
|
|
|
+ int newValue = (int)parameter.Item2;
|
|
|
+ // 尝试写入Channel(非阻塞)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 如果Channel满了(有旧值),DropOldest策略会自动丢弃旧值
|
|
|
+ await _brightnessChannel.Writer.WriteAsync(
|
|
|
+ (channel.GlobalIndex, newValue),
|
|
|
+ _cancellationTokenSource.Token);
|
|
|
+ }
|
|
|
+ catch (OperationCanceledException)
|
|
|
+ {
|
|
|
+ // 正常取消,无需处理
|
|
|
+ }
|
|
|
+ catch (ChannelClosedException)
|
|
|
+ {
|
|
|
+ // Channel已关闭
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("产品实时图像界面-设置光源通道亮度时出错!", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 关闭光源
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="parameter"></param>
|
|
|
+ async void ExecuteTurnOffCommand(object parameter)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!(parameter is ChannelConfig channel)) return;
|
|
|
+ await _lightManagerService.TurnOffGlobalChannelAsync(channel.GlobalIndex);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("关闭通道光源时出错!", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 打开光源
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="parameter"></param>
|
|
|
+ async void ExecuteTurnOnCommand(object parameter)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!(parameter is ChannelConfig channel)) return;
|
|
|
+ await _lightManagerService.TurnOnGlobalChannelAsync(channel.GlobalIndex);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("打开通道光源时出错!", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
void ExecuteLightValueSubCommand()
|
|
|
{
|
|
|
SelectProcedure.LightValue--;
|