//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人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
}