//------------------------------------------------------------------------------ // 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 // 此代码版权(除特别声明外的代码)归作者本人Diego所有 // 源代码使用协议遵循本仓库的开源协议及附加协议 // Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway // Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway // 使用文档:https://thingsgateway.cn/ // QQ群:605534569 //------------------------------------------------------------------------------ using BootstrapBlazor.Components; using System.Collections.Concurrent; using ThingsGateway.Extension.Generic; namespace ThingsGateway.Gateway.Application; /// /// 设备状态变化委托,用于通知设备状态发生变化时的事件 /// /// 设备运行时对象 /// 设备数据对象 public delegate void DelegateOnDeviceChanged(DeviceRuntime deviceRuntime, DeviceBasicData deviceData); /// /// 变量改变事件委托,用于通知变量值发生变化时的事件 /// /// 变量运行时对象 /// 变量数据对象 public delegate void VariableChangeEventHandler(VariableRuntime variableRuntime, VariableBasicData variableData); /// /// 变量采集事件委托,用于通知变量进行采集时的事件 /// /// 变量运行时对象 public delegate void VariableCollectEventHandler(VariableRuntime variableRuntime); /// /// 变量报警事件委托 /// public delegate void VariableAlarmEventHandler(AlarmVariable alarmVariable); public delegate void PluginEventHandler(PluginEventData data); public class PluginEventData { public string DeviceName { get; set; } public Newtonsoft.Json.Linq.JObject Value { get; set; } public string ValueType { get; set; } [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonIgnore] public object ObjectValue { get; set; } //public object ObjectValue => ValueType.IsNullOrEmpty() ? Value : Value.ToObject(Type.GetType(ValueType, false) ?? typeof(JObject)); public PluginEventData(string deviceName, object value) { DeviceName = deviceName; ObjectValue = value; Value = Newtonsoft.Json.Linq.JObject.FromObject(value); ValueType = $"{value?.GetType().FullName},{value?.GetType().Assembly.GetName().Name}"; } } /// /// 采集设备值与状态全局提供类,用于提供全局的设备状态和变量数据的管理 /// public static class GlobalData { /// /// 设备状态变化事件,当设备状态发生变化时触发该事件 /// public static event DelegateOnDeviceChanged DeviceStatusChangeEvent; /// /// 变量值改变事件,当变量值发生改变时触发该事件 /// public static event VariableChangeEventHandler VariableValueChangeEvent; /// /// 变量采集事件,当变量进行采集时触发该事件 /// internal static event VariableCollectEventHandler? VariableCollectChangeEvent; /// /// 报警变化事件 /// public static event VariableAlarmEventHandler? AlarmChangedEvent; public static event PluginEventHandler? PluginEventHandler; public static async Task> GetCurrentUserChannels() { var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false); return ReadOnlyIdChannels.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询 .WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value); } public static async Task> GetCurrentUserDevices() { var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false); return ReadOnlyIdDevices.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询 .WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value); } public static async Task> GetCurrentUserIdVariables() { var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false); return IdVariables.Where(a => a.Value.IsInternalMemoryVariable == false).WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询 .WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value); } public static async Task> GetCurrentUserRealAlarmVariablesAsync() { var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false); return RealAlarmIdVariables.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询 .WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value); } public static async Task> GetCurrentUserAlarmEnableVariables() { var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false); return AlarmEnableIdVariables.Where(a => a.Value.IsInternalMemoryVariable == false).WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询 .WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value); } public static bool ContainsVariable(long businessDeviceId, VariableRuntime a) { if (GlobalData.IdDevices.TryGetValue(businessDeviceId, out var deviceRuntime)) { if (deviceRuntime.Driver is BusinessBase businessBase) { if (businessBase.DriverProperties is IBusinessPropertyAllVariableBase property && property.IsAllVariable) { if (a.IsInternalMemoryVariable == false) return true; } else if (businessBase.RefreshRuntimeAlways) { return true; } } if (deviceRuntime.Driver?.IdVariableRuntimes?.TryGetValue(a.Id, out var oldVariableRuntime) == true) { return true; } } return a.VariablePropertys?.ContainsKey(businessDeviceId) == true; } public static DeviceRuntime[] GetAllVariableBusinessDeviceRuntime() { var channelDevice = GlobalData.IdDevices.Where(a => { if (a.Value.Driver is BusinessBase businessBase) { if (businessBase.DriverProperties is IBusinessPropertyAllVariableBase property && property.IsAllVariable) { return true; } else if (businessBase.RefreshRuntimeAlways) { return true; } } return false; }).Select(a => a.Value).ToArray(); return channelDevice; } public static IDriver[] GetAllVariableBusinessDriver() { var channelDevice = GlobalData.IdDevices.Where(a => { if (a.Value.Driver is BusinessBase businessBase) { if (businessBase.DriverProperties is IBusinessPropertyAllVariableBase property && property.IsAllVariable) { return true; } else if (businessBase.RefreshRuntimeAlways) { return true; } } return false; }).Select(a => a.Value.Driver).ToArray(); return channelDevice; } /// /// 只读的通道字典,提供对通道的只读访问 /// public static IEnumerable GetEnableChannels() { return IdChannels.Where(a => a.Value.Enable).Select(a => a.Value); } public static VariableRuntime GetVariable(string deviceName, string variableName) { if (Devices.TryGetValue(deviceName, out var device)) { if (device.VariableRuntimes.TryGetValue(variableName, out var variable)) { return variable; } } return null; } public static VariableRuntime GetVariable(string variableName) { if (string.IsNullOrEmpty(variableName)) return null; var names = variableName.Split('.'); if (names.Length > 2) return null; if (names.Length == 1) { if (MemoryVariables.TryGetValue(names[0], out var variable)) { return variable; } } else if (Devices.TryGetValue(names[0], out var device)) { if (device.VariableRuntimes.TryGetValue(names[1], out var variable)) { return variable; } } return null; } public static IEnumerable GetEnableDevices() { var idSet = GetRedundantDeviceIds(); return IdDevices.Where(a => a.Value.Enable && !idSet.Contains(a.Value.Id)).Select(a => a.Value); } public static HashSet GetRedundantDeviceIds() { return IdDevices.Select(a => a.Value).Where(a => a.RedundantEnable && a.RedundantDeviceId != null).Select(a => a.RedundantDeviceId ?? 0).ToHashSet(); } public static bool IsRedundant(long deviceId) { if (GlobalData.IdDevices.TryGetValue(deviceId, out var deviceRuntime)) { if (deviceRuntime.RedundantEnable && deviceRuntime.RedundantDeviceId != null) return true; else if (GlobalData.IdDevices.Any(a => a.Value.RedundantDeviceId == deviceRuntime.Id)) { return true; } } return false; } public static bool IsRedundantEnable(long deviceId) { if (GlobalData.IdDevices.TryGetValue(deviceId, out var deviceRuntime)) { if (deviceRuntime.RedundantEnable && deviceRuntime.RedundantDeviceId != null) return true; } return false; } public static IEnumerable GetEnableVariables() { return IdVariables.Where(a => a.Value.DeviceRuntime?.Enable != false && a.Value.DeviceRuntime?.ChannelRuntime?.Enable != false && a.Value?.Enable == true).Select(a => a.Value); } public static bool TryGetDeviceThreadManage(DeviceRuntime deviceRuntime, out IDeviceThreadManage deviceThreadManage) { if (deviceRuntime.Driver?.DeviceThreadManage != null) { deviceThreadManage = deviceRuntime.Driver.DeviceThreadManage; return true; } return GlobalData.ChannelThreadManage.DeviceThreadManages.TryGetValue(deviceRuntime.ChannelId, out deviceThreadManage); } public static IChannelThreadManage GetChannelThreadManage(ChannelRuntime channelRuntime) { if (channelRuntime.DeviceThreadManage?.ChannelThreadManage != null) return channelRuntime.DeviceThreadManage.ChannelThreadManage; else return GlobalData.ChannelThreadManage; } public static Dictionary> GetDeviceThreadManages(IEnumerable deviceRuntimes) { Dictionary> deviceThreadManages = new(); foreach (var item in deviceRuntimes) { if (TryGetDeviceThreadManage(item, out var deviceThreadManage)) { if (deviceThreadManages.TryGetValue(deviceThreadManage, out List? value)) { value.Add(item); } else { deviceThreadManages.Add(deviceThreadManage, new List { item }); } } } return deviceThreadManages; } #region 单例服务 private static IDispatchService channelRuntimeDispatchService; public static IDispatchService ChannelDeviceRuntimeDispatchService { get { if (channelRuntimeDispatchService == null) channelRuntimeDispatchService = App.GetService>(); return channelRuntimeDispatchService; } } private static IDispatchService variableRuntimeDispatchService; public static IDispatchService VariableRuntimeDispatchService { get { if (variableRuntimeDispatchService == null) variableRuntimeDispatchService = App.GetService>(); return variableRuntimeDispatchService; } } private static ISysUserService sysUserService; public static ISysUserService SysUserService { get { if (sysUserService == null) { sysUserService = App.RootServices.GetRequiredService(); } return sysUserService; } } private static IVariableRuntimeService variableRuntimeService; public static IVariableRuntimeService VariableRuntimeService { get { if (variableRuntimeService == null) { variableRuntimeService = App.RootServices.GetRequiredService(); } return variableRuntimeService; } } private static IDeviceRuntimeService deviceRuntimeService; public static IDeviceRuntimeService DeviceRuntimeService { get { if (deviceRuntimeService == null) { deviceRuntimeService = App.RootServices.GetRequiredService(); } return deviceRuntimeService; } } private static IChannelRuntimeService channelRuntimeService; public static IChannelRuntimeService ChannelRuntimeService { get { if (channelRuntimeService == null) { channelRuntimeService = App.RootServices.GetRequiredService(); } return channelRuntimeService; } } private static IChannelThreadManage channelThreadManage; public static IChannelThreadManage ChannelThreadManage { get { if (channelThreadManage == null) { channelThreadManage = App.RootServices.GetRequiredService(); } return channelThreadManage; } } private static IGatewayMonitorHostedService gatewayMonitorHostedService; public static IGatewayMonitorHostedService GatewayMonitorHostedService { get { if (gatewayMonitorHostedService == null) { gatewayMonitorHostedService = App.RootServices.GetRequiredService(); } return gatewayMonitorHostedService; } } private static IRpcService rpcService; public static IRpcService RpcService { get { if (rpcService == null) { rpcService = App.RootServices.GetRequiredService(); } return rpcService; } } private static IAlarmHostedService alarmHostedService; public static IAlarmHostedService AlarmHostedService { get { if (alarmHostedService == null) { alarmHostedService = App.RootServices.GetRequiredService(); } return alarmHostedService; } } private static IHardwareJob? hardwareJob; public static IHardwareJob HardwareJob { get { hardwareJob ??= App.RootServices.GetRequiredService(); return hardwareJob; } } private static IPluginService? pluginService; public static IPluginService PluginService { get { pluginService ??= App.RootServices.GetRequiredService(); return pluginService; } } private static IChannelService? channelService; internal static IChannelService ChannelService { get { channelService ??= App.RootServices.GetRequiredService(); return channelService; } } private static IDeviceService? deviceService; internal static IDeviceService DeviceService { get { deviceService ??= App.RootServices.GetRequiredService(); return deviceService; } } private static IVariableService? variableService; internal static IVariableService VariableService { get { variableService ??= App.RootServices.GetRequiredService(); return variableService; } } private static IGatewayRedundantSerivce? gatewayRedundantSerivce; private static IGatewayRedundantSerivce? GatewayRedundantSerivce { get { gatewayRedundantSerivce ??= App.RootServices.GetService(); return gatewayRedundantSerivce; } } /// /// 采集通道是否可用 /// public static bool StartCollectChannelEnable => GatewayRedundantSerivce?.StartCollectChannelEnable ?? true; /// /// 业务通道是否可用 /// public static bool StartBusinessChannelEnable => GatewayRedundantSerivce?.StartBusinessChannelEnable ?? true; #endregion /// /// 只读的通道字典,提供对通道的只读访问 /// public static IReadOnlyDictionary ReadOnlyIdChannels => IdChannels; /// /// 只读的通道字典,提供对通道的只读访问 /// public static IReadOnlyDictionary ReadOnlyChannels => Channels; /// /// 内部使用的通道字典,用于存储通道对象 /// internal static NonBlockingDictionary IdChannels { get; } = new(); /// /// 内部使用的通道字典,用于存储通道对象 /// internal static NonBlockingDictionary Channels { get; } = new(); /// /// 只读的设备字典,提供对设备的只读访问 /// public static IReadOnlyDictionary ReadOnlyIdDevices => IdDevices; /// /// 只读的设备字典,提供对设备的只读访问 /// public static IReadOnlyDictionary ReadOnlyDevices => Devices; /// /// 内部使用的设备字典,用于存储设备对象 /// internal static NonBlockingDictionary Devices { get; } = new(); /// /// 内部使用的设备字典,用于存储设备对象 /// internal static NonBlockingDictionary IdDevices { get; } = new(); /// /// 内部使用的报警配置变量字典 /// internal static NonBlockingDictionary AlarmEnableIdVariables { get; } = new(); /// /// 内部使用的报警配置变量字典 /// internal static NonBlockingDictionary RealAlarmIdVariables { get; } = new(); /// /// 内部使用的变量字典,用于存储变量对象 /// internal static NonBlockingDictionary IdVariables { get; } = new(); internal static NonBlockingDictionary MemoryVariables { get; } = new(); public static IReadOnlyDictionary ReadOnlyMemoryVariables => MemoryVariables; /// /// 实时报警列表 /// public static IReadOnlyDictionary ReadOnlyRealAlarmIdVariables => RealAlarmIdVariables; /// /// 只读的变量字典 /// public static IReadOnlyDictionary ReadOnlyIdVariables => IdVariables; #region 变化事件 /// /// 报警状态变化处理方法,用于处理报警状态变化时的逻辑 /// /// 报警变量 internal static void AlarmChange(AlarmVariable alarmVariable) { // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 AlarmChangedEvent?.Invoke(alarmVariable); } /// /// 事件状态变化处理方法,用于处理事件状态变化时的逻辑 /// public static void PluginEventChange(PluginEventData pluginEventData) { // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 PluginEventHandler?.Invoke(pluginEventData); } /// /// 设备状态变化处理方法,用于处理设备状态变化时的逻辑 /// /// 设备运行时对象 internal static void DeviceStatusChange(DeviceRuntime deviceRuntime) { deviceRuntime.Driver?.LogMessage?.LogInformation($"Status changed: {deviceRuntime.DeviceStatus}"); // 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递 DeviceStatusChangeEvent?.Invoke(deviceRuntime, deviceRuntime.AdaptDeviceBasicData()); } /// /// 变量值变化处理方法,用于处理变量值发生变化时的逻辑 /// /// 变量运行时对象 internal static void VariableValueChange(VariableRuntime variableRuntime) { // 触发变量值变化事件,并将变量运行时对象转换为变量数据对象进行传递 VariableValueChangeEvent?.Invoke(variableRuntime, variableRuntime.AdaptVariableBasicData()); } /// /// 变量采集处理方法,用于处理变量进行采集时的逻辑 /// /// 变量运行时对象 internal static void VariableCollectChange(VariableRuntime variableRuntime) { // 触发变量采集事件,并将变量运行时对象转换为变量数据对象进行传递 VariableCollectChangeEvent?.Invoke(variableRuntime); } #endregion }