😀 OPCUAServer支持历史查询数据

This commit is contained in:
2248356998 qq.com
2023-03-31 18:32:55 +08:00
parent cd57548a48
commit 130600521c
2 changed files with 46 additions and 17 deletions

View File

@@ -25,12 +25,12 @@
#### 社区版上传插件
> 支持Rpc写入
- Modbus Server
- OPCUA Server
- Mqtt Server
- Mqtt Client
- OPCUA Server (支持历史查询)
- Mqtt Server (支持自定义json)
- Mqtt Client (支持自定义json)
> 不支持Rpc
- RabbitMQ
- RabbitMQ (支持自定义json)
#### nuget

View File

@@ -27,12 +27,18 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
private Dictionary<NodeId, OPCUATag> _idTags = new Dictionary<NodeId, OPCUATag>();
private RpcCore _rpcCore;
private IServiceScope _serviceScope;
private TypeAdapterConfig _config;
/// <inheritdoc cref="ThingsGatewayNodeManager"/>
public ThingsGatewayNodeManager(IServiceScope serviceScope, IServerInternal server, ApplicationConfiguration configuration) : base(server, configuration, ReferenceServer)
{
_serviceScope = serviceScope;
_rpcCore = serviceScope.ServiceProvider.GetService<RpcCore>();
_globalCollectDeviceData = serviceScope.ServiceProvider.GetService<GlobalCollectDeviceData>();
_config = new TypeAdapterConfig();
_config.ForType<ValueHis, DataValue>()
.Map(dest => dest.WrappedValue, (src) => new Variant(src.Value))
.Map(dest => dest.SourceTimestamp, (src) => src.CollectTime)
.Map(dest => dest.StatusCode, (src) => src.Quality == 192 ? StatusCodes.Good : StatusCodes.Bad);
}
@@ -86,12 +92,20 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
}
/// <summary>
/// 读取历史数据
/// </summary>
public override void HistoryRead(OperationContext context, HistoryReadDetails details, TimestampsToReturn timestampsToReturn, bool releaseContinuationPoints, IList<HistoryReadValueId> nodesToRead, IList<HistoryReadResult> results, IList<ServiceResult> errors)
public override void HistoryRead(OperationContext context,
HistoryReadDetails details,
TimestampsToReturn timestampsToReturn,
bool releaseContinuationPoints,
IList<HistoryReadValueId> nodesToRead,
IList<HistoryReadResult> results,
IList<ServiceResult> errors)
{
ReadProcessedDetails readDetail = details as ReadProcessedDetails;
base.HistoryRead(context, details, timestampsToReturn, releaseContinuationPoints, nodesToRead, results, errors);
var readDetail = details as ReadRawModifiedDetails;
//必须带有时间范围
if (readDetail == null || readDetail.StartTime == DateTime.MinValue || readDetail.EndTime == DateTime.MinValue)
{
@@ -127,10 +141,17 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
if (data.Count > 0)
{
var hisDataValue = data.Adapt<List<DataValue>>(_config);
HistoryData hisData = new HistoryData();
hisData.DataValues.AddRange(hisDataValue);
errors[i] = StatusCodes.Good;
//切记Processed设为true否则客户端会报错
historyRead.Processed = true;
results[i] = new HistoryReadResult()
{
StatusCode = StatusCodes.Good,
HistoryData = new ExtensionObject(data)
HistoryData = new ExtensionObject(hisData)
};
}
else
@@ -149,7 +170,6 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
};
}
}
base.HistoryRead(context, details, timestampsToReturn, releaseContinuationPoints, nodesToRead, results, errors);
}
/// <inheritdoc/>
public override NodeId New(ISystemContext context, NodeState node)
@@ -263,15 +283,13 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
variable.WriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description;
variable.UserWriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description;
variable.ValueRank = ValueRanks.Scalar;
variable.Id = variableRunTime.Id;
variable.DataType = DataNodeType(variableRunTime);
var level = ProtectTypeTrans(variableRunTime.ProtectTypeEnum);
var level = ProtectTypeTrans(variableRunTime);
variable.AccessLevel = level;
variable.UserAccessLevel = level;
variable.Historizing = variableRunTime.HisEnable;
variable.Historizing = false;
variable.StatusCode = StatusCodes.Good;
variable.Timestamp = DateTime.Now;
variable.Value = Opc.Ua.TypeInfo.GetDefaultValue(variable.DataType, ValueRanks.Scalar, Server.TypeTree);
@@ -367,15 +385,26 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
}
private byte ProtectTypeTrans(ProtectTypeEnum protectTypeEnum)
private byte ProtectTypeTrans(CollectVariableRunTime variableRunTime)
{
switch (protectTypeEnum)
byte result = 0;
switch (variableRunTime.ProtectTypeEnum)
{
case ProtectTypeEnum.ReadOnly: return AccessLevels.CurrentRead;
case ProtectTypeEnum.ReadOnly:
result = (byte)(result | AccessLevels.CurrentRead);
break;
case ProtectTypeEnum.ReadWrite:
return AccessLevels.CurrentReadOrWrite;
result = (byte)(result | AccessLevels.CurrentReadOrWrite);
break;
default:
return AccessLevels.CurrentRead;
result = (byte)(result | AccessLevels.CurrentRead);
break;
}
if (variableRunTime.HisEnable)
{
result = (byte)(result | AccessLevels.HistoryRead);
}
return result;
}
}