/// <summary> /// Convert to node model /// </summary> /// <param name="attributes"></param> /// <param name="isProperty"></param> /// <returns></returns> public static BaseNodeModel ToNodeModel(this INodeAttributes attributes, bool isProperty = false) { BaseNodeModel nodeModel; var nodeClass = attributes.NodeClass; switch (nodeClass) { case NodeClass.View: nodeModel = new ViewNodeModel { ContainsNoLoops = attributes.ContainsNoLoops, EventNotifier = attributes.EventNotifier }; break; case NodeClass.ReferenceType: case NodeClass.DataType: case NodeClass.ObjectType: case NodeClass.VariableType: switch (nodeClass) { case NodeClass.VariableType: if (isProperty) { nodeModel = new PropertyTypeNodeModel(); } else { nodeModel = new DataVariableTypeNodeModel(); } var baseVariableTypeState = nodeModel as VariableTypeNodeModel; baseVariableTypeState.ArrayDimensions = attributes.ArrayDimensions; baseVariableTypeState.DataType = attributes.DataType; baseVariableTypeState.ValueRank = attributes.ValueRank; baseVariableTypeState.Value = attributes.Value; break; case NodeClass.ObjectType: nodeModel = new ObjectTypeNodeModel(); break; case NodeClass.ReferenceType: nodeModel = new ReferenceTypeNodeModel { Symmetric = attributes.Symmetric, InverseName = attributes.InverseName }; break; default: return(null); } var baseTypeState = nodeModel as TypeNodeModel; baseTypeState.IsAbstract = attributes.IsAbstract; break; case NodeClass.Object: case NodeClass.Method: case NodeClass.Variable: switch (nodeClass) { case NodeClass.Variable: if (isProperty) { nodeModel = new PropertyNodeModel(); } else { nodeModel = new DataVariableNodeModel(); } var baseVariableState = nodeModel as VariableNodeModel; baseVariableState.ArrayDimensions = attributes.ArrayDimensions; baseVariableState.DataType = attributes.DataType; baseVariableState.ValueRank = attributes.ValueRank; baseVariableState.Value = attributes.Value; baseVariableState.AccessLevel = attributes.AccessLevel; baseVariableState.UserAccessLevel = attributes.UserAccessLevel; baseVariableState.Historizing = attributes.Historizing; baseVariableState.MinimumSamplingInterval = attributes.MinimumSamplingInterval; break; case NodeClass.Object: nodeModel = new ObjectNodeModel { EventNotifier = attributes.EventNotifier }; break; case NodeClass.Method: nodeModel = new MethodNodeModel { UserExecutable = attributes.UserExecutable ?? true, Executable = attributes.Executable ?? true }; break; default: return(null); } break; default: return(null); } nodeModel.BrowseName = attributes.BrowseName; nodeModel.Description = attributes.Description; nodeModel.DisplayName = attributes.DisplayName; nodeModel.NodeId = attributes.LocalId; nodeModel.WriteMask = (AttributeWriteMask?)attributes.WriteMask; nodeModel.UserWriteMask = (AttributeWriteMask?)attributes.UserWriteMask; nodeModel.AccessRestrictions = attributes.AccessRestrictions; nodeModel.RolePermissions = attributes.RolePermissions.ToListSafe(); nodeModel.UserRolePermissions = attributes.UserRolePermissions.ToListSafe(); if (attributes is NodeAttributeSet raw) { foreach (var reference in raw.References) { if (nodeModel is InstanceNodeModel instance) { if (reference.ReferenceTypeId == ReferenceTypeIds.HasModellingRule && !reference.IsInverse) { instance.ModellingRuleId = (NodeId)reference.TargetId; } else if (reference.ReferenceTypeId == ReferenceTypeIds.HasTypeDefinition && !reference.IsInverse) { instance.TypeDefinitionId = (NodeId)reference.TargetId; } } else if (nodeModel is TypeNodeModel type) { if (reference.ReferenceTypeId == ReferenceTypeIds.HasSubtype && !reference.IsInverse) { type.SuperTypeId = (NodeId)reference.TargetId; } } else { nodeModel.AddReference(reference.ReferenceTypeId, reference.IsInverse, reference.TargetId); } } } return(nodeModel); }
/// <summary> /// Decode nodeset node to node state /// </summary> /// <param name="vertex"></param> /// <param name="dataTypeId"></param> /// <param name="nodeReferences"></param> /// <param name="rolePermissions"></param> /// <param name="userRolePermissions"></param> /// <param name="codec"></param> /// <param name="context"></param> /// <returns></returns> public static BaseNodeModel ToNodeModel(this BaseNodeVertexModel vertex, string dataTypeId, IEnumerable <ReferenceNodeVertexModel> nodeReferences, IEnumerable <RolePermissionEdgeModel> rolePermissions, IEnumerable <RolePermissionEdgeModel> userRolePermissions, IVariantEncoder codec, ServiceMessageContext context) { BaseNodeModel decoded; switch (vertex) { case ObjectNodeVertexModel uaObject: decoded = new ObjectNodeModel(null) { EventNotifier = (byte?)uaObject.EventNotifier }; break; case PropertyNodeVertexModel uaProperty: decoded = new PropertyNodeModel(null) { DataType = dataTypeId.ToNodeId(context), ValueRank = (int?)uaProperty.ValueRank, ArrayDimensions = uaProperty.ArrayDimensions, AccessLevelEx = (uint?)uaProperty.AccessLevel, AccessLevel = uaProperty.AccessLevel == null ? null : (byte?)((uint)uaProperty.AccessLevel.Value & 0xff), UserAccessLevel = uaProperty.UserAccessLevel == null ? null : (byte?)((uint)uaProperty.UserAccessLevel.Value & 0xff), MinimumSamplingInterval = uaProperty.MinimumSamplingInterval, Historizing = uaProperty.Historizing, Value = codec.Decode(uaProperty.Value, uaProperty.BuiltInType, context), TypeDefinitionId = null }; break; case VariableNodeVertexModel uaVariable: decoded = new DataVariableNodeModel(null) { DataType = dataTypeId.ToNodeId(context), ValueRank = (int?)uaVariable.ValueRank, ArrayDimensions = uaVariable.ArrayDimensions, AccessLevelEx = (uint?)uaVariable.AccessLevel, AccessLevel = uaVariable.AccessLevel == null ? null : (byte?)((uint)uaVariable.AccessLevel.Value & 0xFF), UserAccessLevel = uaVariable.UserAccessLevel == null ? null : (byte?)((uint)uaVariable.UserAccessLevel.Value & 0xff), MinimumSamplingInterval = uaVariable.MinimumSamplingInterval, Historizing = uaVariable.Historizing, Value = codec.Decode(uaVariable.Value, uaVariable.BuiltInType, context), TypeDefinitionId = null }; break; case MethodNodeVertexModel uaMethod: decoded = new MethodNodeModel(null) { Executable = uaMethod.Executable ?? false, UserExecutable = uaMethod.UserExecutable ?? false, TypeDefinitionId = null }; break; case ViewNodeVertexModel uaView: decoded = new ViewNodeModel { ContainsNoLoops = uaView.ContainsNoLoops }; break; case ObjectTypeNodeVertexModel uaObjectType: decoded = new ObjectTypeNodeModel { IsAbstract = uaObjectType.IsAbstract }; break; case PropertyTypeNodeVertexModel uaPropertyType: decoded = new PropertyTypeNodeModel { IsAbstract = uaPropertyType.IsAbstract, DataType = dataTypeId.ToNodeId(context), ValueRank = (int?)uaPropertyType.ValueRank, ArrayDimensions = uaPropertyType.ArrayDimensions, Value = codec.Decode(uaPropertyType.Value, uaPropertyType.BuiltInType, context) }; break; case VariableTypeNodeVertexModel uaVariableType: decoded = new DataVariableTypeNodeModel { IsAbstract = uaVariableType.IsAbstract, DataType = dataTypeId.ToNodeId(context), ValueRank = (int?)uaVariableType.ValueRank, ArrayDimensions = uaVariableType.ArrayDimensions, Value = codec.Decode(uaVariableType.Value, uaVariableType.BuiltInType, context) }; break; case DataTypeNodeVertexModel uaDataType: decoded = new DataTypeNodeModel { IsAbstract = uaDataType.IsAbstract, Definition = uaDataType.DataTypeDefinition == null ? null : (DataTypeDefinition)(codec.Decode(uaDataType.DataTypeDefinition, BuiltInType.ExtensionObject, context).Value as ExtensionObject)?.Body, Purpose = Opc.Ua.Nodeset.Schema.DataTypePurpose.Normal }; break; case ReferenceTypeNodeVertexModel uaReferenceType: decoded = new ReferenceTypeNodeModel { IsAbstract = uaReferenceType.IsAbstract, InverseName = uaReferenceType.InverseName.ToLocalizedText(), Symmetric = uaReferenceType.Symmetric }; break; default: return(null); } decoded.NodeId = vertex.NodeId; decoded.BrowseName = vertex.BrowseName.ToQualifiedName(context); decoded.DisplayName = vertex.DisplayName.ToLocalizedText(); decoded.Description = vertex.Description.ToLocalizedText(); decoded.WriteMask = (AttributeWriteMask)vertex.WriteMask; decoded.UserWriteMask = (AttributeWriteMask)vertex.UserWriteMask; decoded.RolePermissions = rolePermissions? .Select(r => new RolePermissionType { Permissions = (uint)(PermissionType)(r.Permissions ?? 0), RoleId = r.RoleId.ToNodeId(context) }) .ToList(); decoded.UserRolePermissions = userRolePermissions? .Select(r => new RolePermissionType { Permissions = (uint)(PermissionType)(r.Permissions ?? 0), RoleId = r.RoleId.ToNodeId(context) }) .ToList(); if (!string.IsNullOrEmpty(vertex.SymbolicName)) { decoded.SymbolicName = vertex.SymbolicName; } // Decode references var references = new List <IReference>(); if (nodeReferences != null) { foreach (var reference in nodeReferences) { var referenceTypeId = reference.ReferenceTypeId.ToNodeId(context); var isInverse = reference.TargetId == vertex.NodeId; var targetId = isInverse ? reference.OriginId.ToNodeId(context) : reference.TargetId.ToNodeId(context); if (decoded is InstanceNodeModel instance) { if (referenceTypeId == ReferenceTypeIds.HasModellingRule && !isInverse) { instance.ModellingRuleId = ExpandedNodeId.ToNodeId( targetId, context.NamespaceUris); continue; } if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse) { instance.TypeDefinitionId = ExpandedNodeId.ToNodeId( targetId, context.NamespaceUris); continue; } } if (decoded is TypeNodeModel type) { if (referenceTypeId == ReferenceTypeIds.HasSubtype && isInverse) { type.SuperTypeId = ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris); continue; } } references.Add(new NodeStateReference(referenceTypeId, isInverse, targetId)); } } decoded.AddReferences(references); return(decoded); }
/// <summary> /// Convert to service object /// </summary> /// <param name="state"></param> /// <param name="context"></param> /// <param name="parent"></param> /// <returns></returns> public static BaseNodeModel ToNodeModel(this NodeState state, ISystemContext context, BaseNodeModel parent = null) { BaseNodeModel nodeModel; switch (state) { case ViewState viewState: nodeModel = new ViewNodeModel { ContainsNoLoops = viewState.ContainsNoLoops.ToNullable(false), EventNotifier = viewState.EventNotifier.ToNullable(EventNotifiers.None), }; break; case BaseTypeState typeState: switch (typeState) { case BaseVariableTypeState variableType: switch (variableType) { case BaseDataVariableTypeState data: nodeModel = new DataVariableTypeNodeModel(); break; case PropertyTypeState property: nodeModel = new PropertyTypeNodeModel(); break; default: return(null); } var baseVariableTypeState = nodeModel as VariableTypeNodeModel; baseVariableTypeState.ArrayDimensions = variableType.ArrayDimensions?.ToArray(); baseVariableTypeState.DataType = variableType.DataType; baseVariableTypeState.ValueRank = variableType.ValueRank.ToNullable(ValueRanks.Scalar); baseVariableTypeState.Value = variableType.WrappedValue; break; case BaseObjectTypeState objectType: nodeModel = new ObjectTypeNodeModel(); break; case ReferenceTypeState referenceType: nodeModel = new ReferenceTypeNodeModel { Symmetric = referenceType.Symmetric.ToNullable(false), InverseName = referenceType.InverseName }; break; case DataTypeState dataType: nodeModel = new DataTypeNodeModel { // Definition = dataType.Definition.ToDataTypeDefinition(), Purpose = Schema.DataTypePurpose.Normal }; break; default: return(null); } var baseTypeState = nodeModel as TypeNodeModel; baseTypeState.IsAbstract = typeState.IsAbstract.ToNullable(false); break; case BaseInstanceState instanceState: switch (instanceState) { case BaseVariableState variable: switch (variable) { case BaseDataVariableState data: nodeModel = new DataVariableNodeModel(parent); break; case PropertyState property: nodeModel = new PropertyNodeModel(parent); break; default: return(null); } var baseVariableState = nodeModel as VariableNodeModel; baseVariableState.ArrayDimensions = variable.ArrayDimensions.ToArray(); baseVariableState.DataType = variable.DataType; baseVariableState.ValueRank = variable.ValueRank.ToNullable(ValueRanks.Scalar); baseVariableState.Value = variable.WrappedValue; baseVariableState.AccessLevel = variable.AccessLevel.ToNullable(AccessLevels.CurrentRead); baseVariableState.UserAccessLevel = variable.UserAccessLevel.ToNullable(AccessLevels.CurrentRead); baseVariableState.IsValueType = variable.IsValueType; baseVariableState.Historizing = variable.Historizing.ToNullable(false); baseVariableState.MinimumSamplingInterval = variable.MinimumSamplingInterval.ToNullable(0.0); baseVariableState.ModellingRuleId = variable.ModellingRuleId; baseVariableState.NumericId = variable.NumericId; baseVariableState.ReferenceTypeId = variable.ReferenceTypeId; baseVariableState.StatusCode = variable.StatusCode.ToNullable(StatusCodes.Good); baseVariableState.Timestamp = variable.Timestamp.ToNullable(DateTime.MinValue); baseVariableState.TypeDefinitionId = variable.TypeDefinitionId; break; case BaseObjectState obj: nodeModel = new ObjectNodeModel(parent) { EventNotifier = obj.EventNotifier.ToNullable(EventNotifiers.None) }; break; case MethodState method: nodeModel = new MethodNodeModel(parent) { UserExecutable = method.UserExecutable, Executable = method.Executable, MethodDeclarationId = method.MethodDeclarationId, }; break; default: return(null); } break; default: return(null); } nodeModel.BrowseName = state.BrowseName; nodeModel.Description = state.Description; nodeModel.DisplayName = state.DisplayName; nodeModel.Handle = state.Handle; nodeModel.NodeId = state.NodeId; nodeModel.SymbolicName = state.SymbolicName; nodeModel.WriteMask = state.WriteMask.ToNullable(AttributeWriteMask.None); nodeModel.UserWriteMask = state.UserWriteMask.ToNullable(AttributeWriteMask.None); var children = new List <BaseInstanceState>(); state.GetChildren(context, children); foreach (var child in children) { nodeModel.AddChild(child.ToNodeModel(context, nodeModel) as InstanceNodeModel); } var references = new List <IReference>(); state.GetReferences(context, references); foreach (var reference in references) { nodeModel.AddReference(reference.ReferenceTypeId, reference.IsInverse, reference.TargetId); } return(nodeModel); }