2024-05-29 19:03:40 +08:00
|
|
|
|
//------------------------------------------------------------------------------
|
2024-04-14 22:51:56 +08:00
|
|
|
|
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
|
|
|
|
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
|
|
|
|
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
|
|
|
|
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
|
|
|
|
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
2024-09-14 18:17:25 +08:00
|
|
|
|
// 使用文档:https://thingsgateway.cn/
|
2024-04-14 22:51:56 +08:00
|
|
|
|
// QQ群:605534569
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
2025-05-29 17:05:06 +08:00
|
|
|
|
using BootstrapBlazor.Components;
|
|
|
|
|
|
2024-12-05 02:13:02 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
2025-01-24 22:42:26 +08:00
|
|
|
|
|
|
|
|
|
using ThingsGateway.Extension.Generic;
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
|
|
|
|
namespace ThingsGateway.Gateway.Application;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设备状态变化委托,用于通知设备状态发生变化时的事件
|
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <param name="deviceRuntime">设备运行时对象</param>
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <param name="deviceData">设备数据对象</param>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public delegate void DelegateOnDeviceChanged(DeviceRuntime deviceRuntime, DeviceBasicData deviceData);
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// 变量改变事件委托,用于通知变量值发生变化时的事件
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <param name="variableRuntime">变量运行时对象</param>
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <param name="variableData">变量数据对象</param>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public delegate void VariableChangeEventHandler(VariableRuntime variableRuntime, VariableBasicData variableData);
|
2025-09-23 01:22:02 +08:00
|
|
|
|
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// 变量采集事件委托,用于通知变量进行采集时的事件
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <param name="variableRuntime">变量运行时对象</param>
|
|
|
|
|
public delegate void VariableCollectEventHandler(VariableRuntime variableRuntime);
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
2025-01-25 16:02:06 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 变量报警事件委托
|
|
|
|
|
/// </summary>
|
|
|
|
|
public delegate void VariableAlarmEventHandler(AlarmVariable alarmVariable);
|
|
|
|
|
|
2025-08-25 12:21:12 +00:00
|
|
|
|
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}";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 采集设备值与状态全局提供类,用于提供全局的设备状态和变量数据的管理
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class GlobalData
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设备状态变化事件,当设备状态发生变化时触发该事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event DelegateOnDeviceChanged DeviceStatusChangeEvent;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 变量值改变事件,当变量值发生改变时触发该事件
|
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public static event VariableChangeEventHandler VariableValueChangeEvent;
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 变量采集事件,当变量进行采集时触发该事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal static event VariableCollectEventHandler? VariableCollectChangeEvent;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// 报警变化事件
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-01-25 16:02:06 +08:00
|
|
|
|
public static event VariableAlarmEventHandler? AlarmChangedEvent;
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
2025-08-25 12:21:12 +00:00
|
|
|
|
public static event PluginEventHandler? PluginEventHandler;
|
|
|
|
|
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static async Task<IEnumerable<ChannelRuntime>> GetCurrentUserChannels()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
|
|
|
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
2025-07-06 01:33:15 +08:00
|
|
|
|
return ReadOnlyIdChannels.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询
|
2025-03-06 00:46:24 +08:00
|
|
|
|
.WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static async Task<IEnumerable<DeviceRuntime>> GetCurrentUserDevices()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
|
|
|
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
2025-02-17 13:31:29 +08:00
|
|
|
|
return ReadOnlyIdDevices.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询
|
2025-03-06 00:46:24 +08:00
|
|
|
|
.WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-09-23 01:22:02 +08:00
|
|
|
|
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static async Task<IEnumerable<VariableRuntime>> GetCurrentUserIdVariables()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
|
|
|
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
2025-09-23 01:22:02 +08:00
|
|
|
|
return IdVariables.Where(a => a.Value.IsInternalMemoryVariable == false).WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询
|
2025-03-06 00:46:24 +08:00
|
|
|
|
.WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
2025-08-08 02:16:05 +08:00
|
|
|
|
public static async Task<IEnumerable<AlarmVariable>> GetCurrentUserRealAlarmVariablesAsync()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
|
|
|
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
2025-03-04 21:09:11 +08:00
|
|
|
|
return RealAlarmIdVariables.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询
|
2025-03-06 00:46:24 +08:00
|
|
|
|
.WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static async Task<IEnumerable<VariableRuntime>> GetCurrentUserAlarmEnableVariables()
|
2025-03-03 18:07:18 +08:00
|
|
|
|
{
|
|
|
|
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
2025-09-23 01:22:02 +08:00
|
|
|
|
return AlarmEnableIdVariables.Where(a => a.Value.IsInternalMemoryVariable == false).WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.Value.CreateOrgId))//在指定机构列表查询
|
2025-03-06 00:46:24 +08:00
|
|
|
|
.WhereIf(dataScope?.Count == 0, u => u.Value.CreateUserId == UserManager.UserId).Select(a => a.Value);
|
2025-03-03 18:07:18 +08:00
|
|
|
|
}
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
2025-02-26 14:40:38 +08:00
|
|
|
|
public static bool ContainsVariable(long businessDeviceId, VariableRuntime a)
|
|
|
|
|
{
|
|
|
|
|
if (GlobalData.IdDevices.TryGetValue(businessDeviceId, out var deviceRuntime))
|
|
|
|
|
{
|
2025-09-19 14:32:34 +08:00
|
|
|
|
|
|
|
|
|
if (deviceRuntime.Driver is BusinessBase businessBase)
|
2025-02-26 14:40:38 +08:00
|
|
|
|
{
|
2025-09-19 14:32:34 +08:00
|
|
|
|
if (businessBase.DriverProperties is IBusinessPropertyAllVariableBase property && property.IsAllVariable)
|
|
|
|
|
{
|
2025-09-23 01:22:02 +08:00
|
|
|
|
if (a.IsInternalMemoryVariable == false)
|
|
|
|
|
return true;
|
2025-09-19 14:32:34 +08:00
|
|
|
|
}
|
|
|
|
|
else if (businessBase.RefreshRuntimeAlways)
|
2025-02-26 14:40:38 +08:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-18 15:44:00 +08:00
|
|
|
|
|
|
|
|
|
if (deviceRuntime.Driver?.IdVariableRuntimes?.TryGetValue(a.Id, out var oldVariableRuntime) == true)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-02-26 14:40:38 +08:00
|
|
|
|
}
|
2025-03-18 15:44:00 +08:00
|
|
|
|
|
2025-02-26 14:40:38 +08:00
|
|
|
|
return a.VariablePropertys?.ContainsKey(businessDeviceId) == true;
|
|
|
|
|
}
|
2025-09-19 14:32:34 +08:00
|
|
|
|
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;
|
2025-02-26 14:40:38 +08:00
|
|
|
|
|
2025-09-19 14:32:34 +08:00
|
|
|
|
}).Select(a => a.Value.Driver).ToArray();
|
|
|
|
|
return channelDevice;
|
|
|
|
|
}
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// 只读的通道字典,提供对通道的只读访问
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static IEnumerable<ChannelRuntime> GetEnableChannels()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
2025-07-06 01:33:15 +08:00
|
|
|
|
return IdChannels.Where(a => a.Value.Enable).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
2025-03-04 21:09:11 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2025-02-06 16:04:49 +08:00
|
|
|
|
|
2025-09-23 01:22:02 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static IEnumerable<DeviceRuntime> GetEnableDevices()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
|
|
|
|
var idSet = GetRedundantDeviceIds();
|
2025-03-06 00:46:24 +08:00
|
|
|
|
return IdDevices.Where(a => a.Value.Enable && !idSet.Contains(a.Value.Id)).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-02-15 20:12:59 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public static HashSet<long> GetRedundantDeviceIds()
|
|
|
|
|
{
|
2025-02-17 13:31:29 +08:00
|
|
|
|
return IdDevices.Select(a => a.Value).Where(a => a.RedundantEnable && a.RedundantDeviceId != null).Select(a => a.RedundantDeviceId ?? 0).ToHashSet();
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-02-14 11:11:12 +08:00
|
|
|
|
|
|
|
|
|
public static bool IsRedundant(long deviceId)
|
|
|
|
|
{
|
2025-02-17 13:31:29 +08:00
|
|
|
|
if (GlobalData.IdDevices.TryGetValue(deviceId, out var deviceRuntime))
|
2025-02-14 11:11:12 +08:00
|
|
|
|
{
|
|
|
|
|
if (deviceRuntime.RedundantEnable && deviceRuntime.RedundantDeviceId != null)
|
|
|
|
|
return true;
|
2025-02-17 13:31:29 +08:00
|
|
|
|
else if (GlobalData.IdDevices.Any(a => a.Value.RedundantDeviceId == deviceRuntime.Id))
|
2025-02-14 11:11:12 +08:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-09-30 15:25:15 +08:00
|
|
|
|
public static bool IsRedundantEnable(long deviceId)
|
|
|
|
|
{
|
|
|
|
|
if (GlobalData.IdDevices.TryGetValue(deviceId, out var deviceRuntime))
|
|
|
|
|
{
|
|
|
|
|
if (deviceRuntime.RedundantEnable && deviceRuntime.RedundantDeviceId != null)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-03-06 00:46:24 +08:00
|
|
|
|
public static IEnumerable<VariableRuntime> GetEnableVariables()
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
2025-09-23 01:22:02 +08:00
|
|
|
|
return IdVariables.Where(a => a.Value.DeviceRuntime?.Enable != false && a.Value.DeviceRuntime?.ChannelRuntime?.Enable != false && a.Value?.Enable == true).Select(a => a.Value);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2024-12-05 02:13:02 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
2025-08-08 18:01:24 +08:00
|
|
|
|
|
|
|
|
|
public static IChannelThreadManage GetChannelThreadManage(ChannelRuntime channelRuntime)
|
|
|
|
|
{
|
|
|
|
|
if (channelRuntime.DeviceThreadManage?.ChannelThreadManage != null)
|
|
|
|
|
return channelRuntime.DeviceThreadManage.ChannelThreadManage;
|
|
|
|
|
else
|
|
|
|
|
return GlobalData.ChannelThreadManage;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public static Dictionary<IDeviceThreadManage, List<DeviceRuntime>> GetDeviceThreadManages(IEnumerable<DeviceRuntime> deviceRuntimes)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<IDeviceThreadManage, List<DeviceRuntime>> deviceThreadManages = new();
|
2024-12-05 02:13:02 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
foreach (var item in deviceRuntimes)
|
|
|
|
|
{
|
|
|
|
|
if (TryGetDeviceThreadManage(item, out var deviceThreadManage))
|
|
|
|
|
{
|
|
|
|
|
if (deviceThreadManages.TryGetValue(deviceThreadManage, out List<DeviceRuntime>? value))
|
|
|
|
|
{
|
|
|
|
|
value.Add(item);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
deviceThreadManages.Add(deviceThreadManage, new List<DeviceRuntime> { item });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return deviceThreadManages;
|
|
|
|
|
}
|
2024-04-14 22:51:56 +08:00
|
|
|
|
|
2024-09-30 01:39:39 +08:00
|
|
|
|
#region 单例服务
|
|
|
|
|
|
2025-05-29 17:05:06 +08:00
|
|
|
|
private static IDispatchService<ChannelRuntime> channelRuntimeDispatchService;
|
|
|
|
|
public static IDispatchService<ChannelRuntime> ChannelDeviceRuntimeDispatchService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (channelRuntimeDispatchService == null)
|
|
|
|
|
channelRuntimeDispatchService = App.GetService<IDispatchService<ChannelRuntime>>();
|
|
|
|
|
|
|
|
|
|
return channelRuntimeDispatchService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private static IDispatchService<VariableRuntime> variableRuntimeDispatchService;
|
|
|
|
|
public static IDispatchService<VariableRuntime> VariableRuntimeDispatchService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (variableRuntimeDispatchService == null)
|
|
|
|
|
variableRuntimeDispatchService = App.GetService<IDispatchService<VariableRuntime>>();
|
|
|
|
|
|
|
|
|
|
return variableRuntimeDispatchService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static ISysUserService sysUserService;
|
|
|
|
|
public static ISysUserService SysUserService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (sysUserService == null)
|
|
|
|
|
{
|
|
|
|
|
sysUserService = App.RootServices.GetRequiredService<ISysUserService>();
|
|
|
|
|
}
|
|
|
|
|
return sysUserService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IVariableRuntimeService variableRuntimeService;
|
|
|
|
|
public static IVariableRuntimeService VariableRuntimeService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (variableRuntimeService == null)
|
|
|
|
|
{
|
|
|
|
|
variableRuntimeService = App.RootServices.GetRequiredService<IVariableRuntimeService>();
|
|
|
|
|
}
|
|
|
|
|
return variableRuntimeService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IDeviceRuntimeService deviceRuntimeService;
|
|
|
|
|
public static IDeviceRuntimeService DeviceRuntimeService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (deviceRuntimeService == null)
|
|
|
|
|
{
|
|
|
|
|
deviceRuntimeService = App.RootServices.GetRequiredService<IDeviceRuntimeService>();
|
|
|
|
|
}
|
|
|
|
|
return deviceRuntimeService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IChannelRuntimeService channelRuntimeService;
|
|
|
|
|
public static IChannelRuntimeService ChannelRuntimeService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (channelRuntimeService == null)
|
|
|
|
|
{
|
|
|
|
|
channelRuntimeService = App.RootServices.GetRequiredService<IChannelRuntimeService>();
|
|
|
|
|
}
|
|
|
|
|
return channelRuntimeService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private static IChannelThreadManage channelThreadManage;
|
|
|
|
|
public static IChannelThreadManage ChannelThreadManage
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (channelThreadManage == null)
|
|
|
|
|
{
|
|
|
|
|
channelThreadManage = App.RootServices.GetRequiredService<IChannelThreadManage>();
|
|
|
|
|
}
|
|
|
|
|
return channelThreadManage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IGatewayMonitorHostedService gatewayMonitorHostedService;
|
|
|
|
|
public static IGatewayMonitorHostedService GatewayMonitorHostedService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (gatewayMonitorHostedService == null)
|
|
|
|
|
{
|
|
|
|
|
gatewayMonitorHostedService = App.RootServices.GetRequiredService<IGatewayMonitorHostedService>();
|
|
|
|
|
}
|
|
|
|
|
return gatewayMonitorHostedService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 01:39:39 +08:00
|
|
|
|
private static IRpcService rpcService;
|
2024-04-14 22:51:56 +08:00
|
|
|
|
public static IRpcService RpcService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (rpcService == null)
|
|
|
|
|
{
|
2024-09-30 01:39:39 +08:00
|
|
|
|
rpcService = App.RootServices.GetRequiredService<IRpcService>();
|
2024-04-14 22:51:56 +08:00
|
|
|
|
}
|
|
|
|
|
return rpcService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 01:39:39 +08:00
|
|
|
|
private static IAlarmHostedService alarmHostedService;
|
|
|
|
|
public static IAlarmHostedService AlarmHostedService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (alarmHostedService == null)
|
|
|
|
|
{
|
|
|
|
|
alarmHostedService = App.RootServices.GetRequiredService<IAlarmHostedService>();
|
|
|
|
|
}
|
|
|
|
|
return alarmHostedService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static IHardwareJob? hardwareJob;
|
2024-09-30 01:39:39 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public static IHardwareJob HardwareJob
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
hardwareJob ??= App.RootServices.GetRequiredService<IHardwareJob>();
|
|
|
|
|
return hardwareJob;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-30 01:39:39 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static IPluginService? pluginService;
|
|
|
|
|
public static IPluginService PluginService
|
2024-09-30 01:39:39 +08:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
pluginService ??= App.RootServices.GetRequiredService<IPluginService>();
|
|
|
|
|
return pluginService;
|
2024-09-30 01:39:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static IChannelService? channelService;
|
|
|
|
|
internal static IChannelService ChannelService
|
2024-09-30 01:39:39 +08:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
channelService ??= App.RootServices.GetRequiredService<IChannelService>();
|
|
|
|
|
return channelService;
|
2024-09-30 01:39:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static IDeviceService? deviceService;
|
|
|
|
|
internal static IDeviceService DeviceService
|
2024-09-30 01:39:39 +08:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
deviceService ??= App.RootServices.GetRequiredService<IDeviceService>();
|
|
|
|
|
return deviceService;
|
2024-09-30 01:39:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
private static IVariableService? variableService;
|
|
|
|
|
internal static IVariableService VariableService
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
variableService ??= App.RootServices.GetRequiredService<IVariableService>();
|
|
|
|
|
return variableService;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IGatewayRedundantSerivce? gatewayRedundantSerivce;
|
|
|
|
|
private static IGatewayRedundantSerivce? GatewayRedundantSerivce
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
gatewayRedundantSerivce ??= App.RootServices.GetService<IGatewayRedundantSerivce>();
|
|
|
|
|
return gatewayRedundantSerivce;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-05 02:13:02 +08:00
|
|
|
|
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// <summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// 采集通道是否可用
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public static bool StartCollectChannelEnable => GatewayRedundantSerivce?.StartCollectChannelEnable ?? true;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 业务通道是否可用
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static bool StartBusinessChannelEnable => GatewayRedundantSerivce?.StartBusinessChannelEnable ?? true;
|
|
|
|
|
#endregion
|
|
|
|
|
|
2025-03-04 21:09:11 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 只读的通道字典,提供对通道的只读访问
|
|
|
|
|
/// </summary>
|
2025-07-06 01:33:15 +08:00
|
|
|
|
public static IReadOnlyDictionary<long, ChannelRuntime> ReadOnlyIdChannels => IdChannels;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 只读的通道字典,提供对通道的只读访问
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static IReadOnlyDictionary<string, ChannelRuntime> ReadOnlyChannels => Channels;
|
2024-07-14 12:18:13 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// 内部使用的通道字典,用于存储通道对象
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<long, ChannelRuntime> IdChannels { get; } = new();
|
2025-07-06 01:33:15 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 内部使用的通道字典,用于存储通道对象
|
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<string, ChannelRuntime> Channels { get; } = new();
|
2024-07-14 12:18:13 +08:00
|
|
|
|
|
2025-03-04 21:09:11 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 只读的设备字典,提供对设备的只读访问
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static IReadOnlyDictionary<long, DeviceRuntime> ReadOnlyIdDevices => IdDevices;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 只读的设备字典,提供对设备的只读访问
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static IReadOnlyDictionary<string, DeviceRuntime> ReadOnlyDevices => Devices;
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 内部使用的设备字典,用于存储设备对象
|
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<string, DeviceRuntime> Devices { get; } = new();
|
2025-02-17 13:31:29 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 内部使用的设备字典,用于存储设备对象
|
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<long, DeviceRuntime> IdDevices { get; } = new();
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <summary>
|
2025-03-04 21:09:11 +08:00
|
|
|
|
/// 内部使用的报警配置变量字典
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<long, VariableRuntime> AlarmEnableIdVariables { get; } = new();
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 内部使用的报警配置变量字典
|
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<long, AlarmVariable> RealAlarmIdVariables { get; } = new();
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 内部使用的变量字典,用于存储变量对象
|
|
|
|
|
/// </summary>
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<long, VariableRuntime> IdVariables { get; } = new();
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
2025-10-15 17:40:33 +08:00
|
|
|
|
internal static NonBlockingDictionary<string, VariableRuntime> MemoryVariables { get; } = new();
|
2025-09-23 01:22:02 +08:00
|
|
|
|
public static IReadOnlyDictionary<string, VariableRuntime> ReadOnlyMemoryVariables => MemoryVariables;
|
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <summary>
|
2025-03-04 21:09:11 +08:00
|
|
|
|
/// 实时报警列表
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// </summary>
|
2025-03-04 21:09:11 +08:00
|
|
|
|
public static IReadOnlyDictionary<long, AlarmVariable> ReadOnlyRealAlarmIdVariables => RealAlarmIdVariables;
|
2024-07-14 12:18:13 +08:00
|
|
|
|
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
2025-03-04 21:09:11 +08:00
|
|
|
|
/// 只读的变量字典
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-03-04 21:09:11 +08:00
|
|
|
|
public static IReadOnlyDictionary<long, VariableRuntime> ReadOnlyIdVariables => IdVariables;
|
2025-01-24 22:42:26 +08:00
|
|
|
|
|
2025-03-04 21:09:11 +08:00
|
|
|
|
#region 变化事件
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 报警状态变化处理方法,用于处理报警状态变化时的逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="alarmVariable">报警变量</param>
|
|
|
|
|
internal static void AlarmChange(AlarmVariable alarmVariable)
|
2024-04-14 22:51:56 +08:00
|
|
|
|
{
|
2025-06-06 21:13:58 +08:00
|
|
|
|
// 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递
|
|
|
|
|
AlarmChangedEvent?.Invoke(alarmVariable);
|
2024-04-14 22:51:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-25 12:21:12 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 事件状态变化处理方法,用于处理事件状态变化时的逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static void PluginEventChange(PluginEventData pluginEventData)
|
|
|
|
|
{
|
|
|
|
|
// 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递
|
|
|
|
|
PluginEventHandler?.Invoke(pluginEventData);
|
|
|
|
|
}
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// <summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// 设备状态变化处理方法,用于处理设备状态变化时的逻辑
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <param name="deviceRuntime">设备运行时对象</param>
|
|
|
|
|
internal static void DeviceStatusChange(DeviceRuntime deviceRuntime)
|
2024-04-14 22:51:56 +08:00
|
|
|
|
{
|
2025-05-16 18:00:36 +08:00
|
|
|
|
deviceRuntime.Driver?.LogMessage?.LogInformation($"Status changed: {deviceRuntime.DeviceStatus}");
|
|
|
|
|
|
2025-06-06 21:13:58 +08:00
|
|
|
|
// 触发设备状态变化事件,并将设备运行时对象转换为设备数据对象进行传递
|
2025-06-28 00:00:43 +08:00
|
|
|
|
DeviceStatusChangeEvent?.Invoke(deviceRuntime, deviceRuntime.AdaptDeviceBasicData());
|
2024-04-14 22:51:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-07-14 12:18:13 +08:00
|
|
|
|
/// 变量值变化处理方法,用于处理变量值发生变化时的逻辑
|
2024-04-14 22:51:56 +08:00
|
|
|
|
/// </summary>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <param name="variableRuntime">变量运行时对象</param>
|
|
|
|
|
internal static void VariableValueChange(VariableRuntime variableRuntime)
|
2024-04-14 22:51:56 +08:00
|
|
|
|
{
|
2025-06-06 21:13:58 +08:00
|
|
|
|
// 触发变量值变化事件,并将变量运行时对象转换为变量数据对象进行传递
|
2025-06-28 00:00:43 +08:00
|
|
|
|
VariableValueChangeEvent?.Invoke(variableRuntime, variableRuntime.AdaptVariableBasicData());
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 变量采集处理方法,用于处理变量进行采集时的逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="variableRuntime">变量运行时对象</param>
|
|
|
|
|
internal static void VariableCollectChange(VariableRuntime variableRuntime)
|
|
|
|
|
{
|
2025-06-06 21:13:58 +08:00
|
|
|
|
// 触发变量采集事件,并将变量运行时对象转换为变量数据对象进行传递
|
|
|
|
|
VariableCollectChangeEvent?.Invoke(variableRuntime);
|
2024-04-14 22:51:56 +08:00
|
|
|
|
}
|
2025-03-04 21:09:11 +08:00
|
|
|
|
|
|
|
|
|
#endregion
|
2024-05-29 19:03:40 +08:00
|
|
|
|
}
|