/// <summary> /// Writes the Value attribute of one or more nodes. /// </summary> /// <param name="nodesToWrite">A list of nodes to write.</param> /// <param name="results">A list of values to write.</param> /// <exception cref="Exception">Throws and forwards any exception with short error description.</exception> public void WriteValues( NodeIdCollection nodesToWrite, DataValueCollection values, out StatusCodeCollection results) { results = null; DiagnosticInfoCollection diagnosticInfos = null; // Build list of attributes to write. WriteValueCollection valuesToWrite = new WriteValueCollection(); try { for (int i = 0; i < nodesToWrite.Count; i++) { WriteValue attributeToWrite = new WriteValue(); attributeToWrite.NodeId = nodesToWrite[i]; // We have to write the Value attribute only: attributeToWrite.AttributeId = Attributes.Value; attributeToWrite.Handle = attributeIdToString(Attributes.Value); // Set the according value: attributeToWrite.Value = values[i]; valuesToWrite.Add(attributeToWrite); } // Actual call to server. m_Session.Write( null, valuesToWrite, out results, out diagnosticInfos); } catch (Exception e) { throw e; } }
public void ReadBuiltInType(IList viList, out List <BuiltInType> types) { if (viList.Count == 0) { types = new List <BuiltInType>(); return; } var nodesToRead = new ReadValueIdCollection(); foreach (Interfaces.IVariableInfo r in viList) { var nodeToRead = new ReadValueId(); nodeToRead.NodeId = this.ToNodeId(r.NodeId); nodeToRead.AttributeId = Attributes.DataType; nodesToRead.Add(nodeToRead); } DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); types = new List <BuiltInType>(); foreach (var r in results) { types.Add(TypeInfo.GetBuiltInType((NodeId)r.Value)); } }
/// <summary> /// Starts reading raw values. /// </summary> /// <param name="context">The context for the operation.</param> /// <param name="request">The request parameters.</param> /// <param name="timestampsToReturn">The timestamps to return with the value.</param> /// <param name="indexRange">The range to return for array values.</param> /// <param name="dataEncoding">The data encoding to use for structured values.</param> /// <param name="values">The values to return.</param> public void BeginReadRaw( #pragma warning disable RECS0154 // Parameter is never used ServerSystemContext context, #pragma warning restore RECS0154 // Parameter is never used ReadRawModifiedDetails request, TimestampsToReturn timestampsToReturn, NumericRange indexRange, QualifiedName dataEncoding, DataValueCollection values) { _request = request; // initialize start and end. _startTime = _request.StartTime; _endTime = _request.EndTime; if (_endTime == DateTime.MinValue) { _endTime = DateTime.MaxValue; } // check the direction. _isForward = _startTime < _endTime; _position = -1; DataValue value = null; // get first bound. if (_request.ReturnBounds) { value = _source.FirstRaw(_startTime, !_isForward, _request.IsReadModified, out _position); if (value != null) { AddValue(timestampsToReturn, indexRange, dataEncoding, values, value); } } }
public DataValueCollection readAttribute(NodeId aNodeId, uint aAttribute) { var lAttributeToRead = new ReadValueId(); lAttributeToRead.NodeId = aNodeId; lAttributeToRead.AttributeId = aAttribute; var lValueIdsToRead = new ReadValueIdCollection(); lValueIdsToRead.Add(lAttributeToRead); DataValueCollection lResults = null; DiagnosticInfoCollection lDiagnosticInfos = null; var lResponse = mSession.Read(null, 0, TimestampsToReturn.Neither, lValueIdsToRead, out lResults, out lDiagnosticInfos); if ((lResults.Count != 1) || (lResults[0].Value == null)) { return(null); } return(lResults); }
/// <summary> /// Reads any attribute of one or more nodes. /// </summary> /// <param name="nodesToRead">A list of nodes to read.</param> /// <param name="results">A list of read results.</param> /// <exception cref="Exception">Throws and forwards any exception with short error description.</exception> public void Read( ReadValueIdCollection nodesToRead, out DataValueCollection results) { results = null; DiagnosticInfoCollection diagnosticInfos = null; try { // The actual call to the server. m_Session.Read( null, 0, TimestampsToReturn.Both, nodesToRead, out results, out diagnosticInfos); } catch (Exception e) { throw e; } }
public DataValueCollection Read(ReadValueIdCollection nodesToRead) { if (nodesToRead == null || nodesToRead.Count == 0) { return(null); } DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = _uaSession.Read( null, 0, TimestampsToReturn.Both, nodesToRead, out values, out diagnosticInfos); ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); return(values); }
/// <summary> /// Reads the value attribute of one or more nodes. /// </summary> /// <param name="nodesToRead">A list of nodes to read.</param> /// <param name="results">A list of data values.</param> /// <exception cref="Exception">Throws and forwards any exception with short error description.</exception> public ResponseHeader ReadValues( NodeIdCollection nodesToRead, out DataValueCollection results) { ResponseHeader response = null; results = null; DiagnosticInfoCollection diagnosticInfos; // build list of attributes to read. ReadValueIdCollection valueIdsToRead = new ReadValueIdCollection(); try { for (int i = 0; i < nodesToRead.Count; i++) { ReadValueId attributeToRead = new ReadValueId(); attributeToRead.NodeId = nodesToRead[i]; attributeToRead.AttributeId = Attributes.Value; attributeToRead.Handle = attributeIdToString(Attributes.Value); valueIdsToRead.Add(attributeToRead); } response = m_Session.Read( null, 0, TimestampsToReturn.Both, valueIdsToRead, out results, out diagnosticInfos); } catch (Exception e) { throw e; } return(response); }
/// <summary> /// Starts reading raw values. /// </summary> /// <param name="context">The context for the operation.</param> /// <param name="request">The request parameters.</param> /// <param name="timestampsToReturn">The timestamps to return with the value.</param> /// <param name="indexRange">The range to return for array values.</param> /// <param name="dataEncoding">The data encoding to use for structured values.</param> /// <param name="values">The values to return.</param> public void BeginReadRaw( ServerSystemContext context, ReadRawModifiedDetails request, TimestampsToReturn timestampsToReturn, NumericRange indexRange, QualifiedName dataEncoding, DataValueCollection values) { m_request = request; // initialize start and end. m_startTime = m_request.StartTime; m_endTime = m_request.EndTime; if (m_endTime == DateTime.MinValue) { m_endTime = DateTime.MaxValue; } // check the direction. m_isForward = m_startTime < m_endTime; m_position = -1; DataValue value = null; // get first bound. if (m_request.ReturnBounds) { value = m_source.FirstRaw(m_startTime, !m_isForward, m_request.IsReadModified, out m_position); if (value != null) { AddValue(timestampsToReturn, indexRange, dataEncoding, values, value); } } }
/// <summary> /// Reads the values for the node attributes and returns a node object. /// </summary> /// <remarks> /// If the nodeclass is known, only the supported attribute values are read. /// </remarks> /// <param name="nodeId">The nodeId.</param> /// <param name="nodeClass">The nodeclass of the node to read.</param> /// <param name="optionalAttributes">Read optional attributes.</param> /// <param name="ct">The cancellation token for the request.</param> public async Task <Node> ReadNodeAsync( NodeId nodeId, NodeClass nodeClass, bool optionalAttributes = true, CancellationToken ct = default) { // build list of attributes. var attributes = CreateAttributes(nodeClass, optionalAttributes); // build list of values to read. ReadValueIdCollection itemsToRead = new ReadValueIdCollection(); foreach (uint attributeId in attributes.Keys) { ReadValueId itemToRead = new ReadValueId { NodeId = nodeId, AttributeId = attributeId }; itemsToRead.Add(itemToRead); } // read from server. ReadResponse readResponse = await ReadAsync( null, 0, TimestampsToReturn.Neither, itemsToRead, ct).ConfigureAwait(false); DataValueCollection values = readResponse.Results; DiagnosticInfoCollection diagnosticInfos = readResponse.DiagnosticInfos; ClientBase.ValidateResponse(values, itemsToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead); return(ProcessReadResponse(readResponse.ResponseHeader, attributes, itemsToRead, values, diagnosticInfos)); }
/// <summary> /// Displays the attributes and properties in the attributes view. /// </summary> /// <param name="sourceId">The NodeId of the Node to browse.</param> private void DisplayAttributes(NodeId sourceId) { try { AttributesView.Items.Clear(); ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); // attempt to read all possible attributes. for (uint ii = Attributes.NodeClass; ii <= Attributes.UserExecutable; ii++) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = sourceId; nodeToRead.AttributeId = ii; nodesToRead.Add(nodeToRead); } int startOfProperties = nodesToRead.Count; // find all of the pror of the node. BrowseDescription nodeToBrowse1 = new BrowseDescription(); nodeToBrowse1.NodeId = sourceId; nodeToBrowse1.BrowseDirection = BrowseDirection.Forward; nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty; nodeToBrowse1.IncludeSubtypes = true; nodeToBrowse1.NodeClassMask = 0; nodeToBrowse1.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); nodesToBrowse.Add(nodeToBrowse1); // fetch property references from the server. ReferenceDescriptionCollection references = Browse(m_server, nodesToBrowse, false); if (references == null) { return; } for (int ii = 0; ii < references.Count; ii++) { // ignore external references. if (references[ii].NodeId.IsAbsolute) { continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = (NodeId)references[ii].NodeId; nodeToRead.AttributeId = Attributes.Value; nodesToRead.Add(nodeToRead); } // read all values. OperationContext context = new OperationContext(new RequestHeader(), RequestType.Browse); DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_server.CurrentInstance.NodeManager.Read( context, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ListViewItem idnode = new ListViewItem("NodeID"); idnode.SubItems.Add(sourceId.ToString()); AttributesView.Items.Add(idnode); // process results. for (int ii = 0; ii < results.Count; ii++) { string name = null; string datatype = null; string value = null; // process attribute value. if (ii < startOfProperties) { // ignore attributes which are invalid for the node. if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid) { continue; } // get the name of the attribute. name = Attributes.GetBrowseName(nodesToRead[ii].AttributeId); // display any unexpected error. if (StatusCode.IsBad(results[ii].StatusCode)) { datatype = Utils.Format("{0}", Attributes.GetDataTypeId(nodesToRead[ii].AttributeId)); value = Utils.Format("{0}", results[ii].StatusCode); } // display the value. else { TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value); datatype = typeInfo.BuiltInType.ToString(); if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions) { datatype += "[]"; } value = Utils.Format("{0}", results[ii].Value); } } // process property value. else { // ignore properties which are invalid for the node. if (results[ii].StatusCode == StatusCodes.BadNodeIdUnknown) { continue; } // get the name of the property. name = Utils.Format("{0}", references[ii - startOfProperties]); // display any unexpected error. if (StatusCode.IsBad(results[ii].StatusCode)) { datatype = String.Empty; value = Utils.Format("{0}", results[ii].StatusCode); } // display the value. else { TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value); datatype = typeInfo.BuiltInType.ToString(); if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions) { datatype += "[]"; } value = Utils.Format("{0}", results[ii].Value); } } // add the attribute name/value to the list view. ListViewItem item = new ListViewItem(name); item.SubItems.Add(value); item.SubItems.Add(datatype); AttributesView.Items.Add(item); } // adjust width of all columns. for (int ii = 0; ii < AttributesView.Columns.Count; ii++) { AttributesView.Columns[ii].Width = -2; } } catch (Exception exception) { ServerUtils.HandleException(this.Text, exception); } }
/// <summary> /// 读取一个节点的指定属性 /// </summary> /// <param name="nodeId"></param> /// <param name="attribute"></param> /// <returns></returns> private DataValue ReadNoteDataValueAttributes(NodeId nodeId, uint attribute) { NodeId sourceId = nodeId; ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = sourceId; nodeToRead.AttributeId = attribute; nodesToRead.Add(nodeToRead); int startOfProperties = nodesToRead.Count; // find all of the pror of the node. BrowseDescription nodeToBrowse1 = new BrowseDescription(); nodeToBrowse1.NodeId = sourceId; nodeToBrowse1.BrowseDirection = BrowseDirection.Forward; nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty; nodeToBrowse1.IncludeSubtypes = true; nodeToBrowse1.NodeClassMask = 0; nodeToBrowse1.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); nodesToBrowse.Add(nodeToBrowse1); // fetch property references from the server. ReferenceDescriptionCollection references = FormUtils.Browse(m_OpcUaClient.Session, nodesToBrowse, false); if (references == null) { return(null); } for (int ii = 0; ii < references.Count; ii++) { // ignore external references. if (references[ii].NodeId.IsAbsolute) { continue; } ReadValueId nodeToRead2 = new ReadValueId(); nodeToRead2.NodeId = (NodeId)references[ii].NodeId; nodeToRead2.AttributeId = Attributes.Value; nodesToRead.Add(nodeToRead2); } // read all values. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_OpcUaClient.Session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); return(results[0]); }
/// <summary> /// Invokes the Read service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="maxAge">The Maximum age of the value to be read in milliseconds.</param> /// <param name="timestampsToReturn">The type of timestamps to be returned for the requested Variables.</param> /// <param name="nodesToRead">The list of Nodes and their Attributes to read.</param> /// <param name="results">The list of returned Attribute values</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader Read( RequestHeader requestHeader, double maxAge, TimestampsToReturn timestampsToReturn, ReadValueIdCollection nodesToRead, out DataValueCollection results, out DiagnosticInfoCollection diagnosticInfos) { OperationContext context = ValidateRequest(requestHeader, RequestType.Read); try { if (nodesToRead == null || nodesToRead.Count == 0) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } m_serverInternal.NodeManager.Read( context, maxAge, timestampsToReturn, nodesToRead, out results, out diagnosticInfos); return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Updates the history. /// </summary> private void InsertReplace(PerformUpdateType updateType) { DataValueCollection values = new DataValueCollection(); foreach (DataRowView row in m_dataset.Tables[0].DefaultView) { DataValue value = (DataValue)row.Row[9]; values.Add(value); } bool isStructured = false; PropertyWithHistory property = PropertyCB.SelectedItem as PropertyWithHistory; if (property != null && property.BrowseName == Opc.Ua.BrowseNames.Annotations) { isStructured = true; } HistoryUpdateResultCollection results = InsertReplace(GetSelectedNode(), updateType, isStructured, values); ResultsDV.Columns[ResultsDV.Columns.Count - 1].Visible = true; for (int ii = 0; ii < m_dataset.Tables[0].DefaultView.Count; ii++) { m_dataset.Tables[0].DefaultView[ii].Row[10] = results[0].OperationResults[ii]; } m_dataset.AcceptChanges(); }
/// <summary> /// Converts a UA value to an HDA attribute value. /// </summary> /// <param name="session">The session.</param> /// <param name="attributeId">The attribute id.</param> /// <param name="values">The values.</param> /// <param name="index">The index.</param> /// <returns></returns> private DaValue GetAttributeValue(Session session, uint attributeId, DataValueCollection values, int index) { switch (attributeId) { case Constants.OPCHDA_DATA_TYPE: { DaValue result = new DaValue(); DataValue value = values[index]; // check for valid node. if (StatusCode.IsBad(value.StatusCode)) { result.Error = ResultIds.E_UNKNOWNITEMID; return result; } // covert to var type. NodeId dataTypeId = value.GetValue<NodeId>(DataTypeIds.BaseDataType); int valueRank = values[index+1].GetValue<int>(ValueRanks.Scalar); BuiltInType builtInType = DataTypes.GetBuiltInType(dataTypeId, session.TypeTree); TypeInfo typeInfo = new TypeInfo(builtInType, valueRank); short varType = (short)ComUtils.GetVarType(typeInfo); result.Value = varType; result.Quality = ComUtils.GetQualityCode(value.StatusCode); result.Timestamp = value.ServerTimestamp; result.Error = ResultIds.S_OK; return result; } case Constants.OPCHDA_DESCRIPTION: { DataValue value = values[index]; if (value.StatusCode == StatusCodes.BadAttributeIdInvalid) { DaValue result = new DaValue(); result.Error = ResultIds.E_INVALIDATTRID; return result; } return m_mapper.GetLocalDataValue(value); } default: { return ComHdaProxy.GetAttributeValue(session, m_mapper, attributeId, values[index]); } } }
/// <summary> /// Reads the history of values for a set of variables at given time. /// </summary> static void HistoryReadAtTime(Session session) { // translate browse paths. IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder, VariableBrowsePaths.ToArray()); DiagnosticInfoCollection diagnosticInfos; ReadAtTimeDetails readDetails = new ReadAtTimeDetails(); readDetails.ReqTimes = new DateTimeCollection(); for (int jj = 0; jj < 10; jj++) { readDetails.ReqTimes.Add(new DateTime(2008, 01, 01, 12, 0, jj)); readDetails.ReqTimes.Add(new DateTime(2008, 01, 01, 12, 0, jj, (int)500)); } ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails); HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection(); for (int ii = 0; ii < nodeIds.Count; ii++) { HistoryReadValueId readValueId = new HistoryReadValueId(); readValueId.NodeId = nodeIds[ii].NodeId; readValueId.Processed = false; idCollection.Add(readValueId); } HistoryReadResultCollection historyReadResults; ResponseHeader responseHeader = session.HistoryRead(null, eo, TimestampsToReturn.Both, true, idCollection, out historyReadResults, out diagnosticInfos); // process results. for (int ii = 0; ii < historyReadResults.Count; ii++) { HistoryReadResult historyReadResult = historyReadResults[ii]; HistoryData historyData = null; DataValueCollection dataValues = null; if (historyReadResult.HistoryData != null) { historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData; dataValues = historyData.DataValues; } ServiceResult result = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader); Console.WriteLine("HistoryRead result code for {0}: {1}", VariableBrowsePaths[ii], result.StatusCode.ToString()); if (StatusCode.IsBad(historyReadResult.StatusCode)) { continue; } if (dataValues == null) { Console.WriteLine("dataValues == null"); continue; } for (int jj = 0; jj < dataValues.Count; jj++) { DataValue dataValue = dataValues[jj]; // write value. Console.WriteLine("{0}: V={1}, Q={2}, SrvT={3}, SrcT={4}", jj, dataValue.Value == null ? "null" : dataValue.Value.ToString(), dataValue.StatusCode.ToString(), dataValue.ServerTimestamp, dataValue.SourceTimestamp); } } }
/// <summary> /// Invokes the Read service. /// </summary> public virtual ResponseHeader Read( RequestHeader requestHeader, double maxAge, TimestampsToReturn timestampsToReturn, ReadValueIdCollection nodesToRead, out DataValueCollection results, out DiagnosticInfoCollection diagnosticInfos) { ReadRequest request = new ReadRequest(); ReadResponse response = null; request.RequestHeader = requestHeader; request.MaxAge = maxAge; request.TimestampsToReturn = timestampsToReturn; request.NodesToRead = nodesToRead; UpdateRequestHeader(request, requestHeader == null, "Read"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (ReadResponse)genericResponse; } else { ReadResponseMessage responseMessage = InnerChannel.Read(new ReadMessage(request)); if (responseMessage == null || responseMessage.ReadResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.ReadResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "Read"); } return response.ResponseHeader; }
/// <summary> /// Finishes an asynchronous invocation of the Read service. /// </summary> public ResponseHeader EndRead( IAsyncResult result, out DataValueCollection results, out DiagnosticInfoCollection diagnosticInfos) { ReadResponse response = null; try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.EndSendRequest(result); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (ReadResponse)genericResponse; } else { ReadResponseMessage responseMessage = InnerChannel.EndRead(result); if (responseMessage == null || responseMessage.ReadResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.ReadResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(null, response, "Read"); } return response.ResponseHeader; }
/// <summary> /// Continues a read raw operation. /// </summary> /// <param name="context">The context for the operation.</param> /// <param name="timestampsToReturn">The timestamps to return with the value.</param> /// <param name="indexRange">The range to return for array values.</param> /// <param name="dataEncoding">The data encoding to use for structured values.</param> /// <param name="values">The values to return.</param> /// <returns>False if the operation halted because the maximum number of values was discovered.</returns> public bool NextReadRaw( ServerSystemContext context, TimestampsToReturn timestampsToReturn, NumericRange indexRange, QualifiedName dataEncoding, DataValueCollection values) { DataValue value = null; do { // check for limit. if (m_request.NumValuesPerNode > 0 && values.Count >= m_request.NumValuesPerNode) { return false; } value = m_source.NextRaw(m_lastTime, m_isForward, m_request.IsReadModified, ref m_position); // no more data. if (value == null) { return true; } // check for bound. if ((m_isForward && value.ServerTimestamp >= m_endTime) || (!m_isForward && value.ServerTimestamp <= m_endTime)) { if (m_request.ReturnBounds) { AddValue(timestampsToReturn, indexRange, dataEncoding, values, value); return true; } } // add value. AddValue(timestampsToReturn, indexRange, dataEncoding, values, value); } while (value != null); return true; }
/// <summary> /// Adds a DataValue to a list of values to return. /// </summary> private void AddValue( TimestampsToReturn timestampsToReturn, NumericRange indexRange, QualifiedName dataEncoding, DataValueCollection values, DataValue value) { // ignore invalid case. if (value == null) { return; } // save the last timestamp returned. m_lastTime = value.ServerTimestamp; // check if the index range or data encoding can be applied. if (StatusCode.IsGood(value.StatusCode)) { object valueToReturn = value.Value; // apply the index range. if (indexRange != NumericRange.Empty) { StatusCode error = indexRange.ApplyRange(ref valueToReturn); if (StatusCode.IsBad(error)) { value.Value = null; value.StatusCode = error; } else { value.Value = valueToReturn; } } // apply the data encoding. if (!QualifiedName.IsNull(dataEncoding)) { value.Value = null; value.StatusCode = StatusCodes.BadDataEncodingUnsupported; } } // apply the timestamps filter. if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Server) { value.SourceTimestamp = DateTime.MinValue; } if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Source) { value.ServerTimestamp = DateTime.MinValue; } // add result. values.Add(value); }
/// <summary> /// Reads the attributes, verifies the results and updates the nodes. /// </summary> private bool Write(WriteValueCollection nodesToWrite) { bool success = true; StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; try { Session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); } catch (System.ServiceModel.CommunicationException e) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } catch (System.Xml.XmlException e) { Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } catch (ServiceResultException e) { if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } throw new ServiceResultException(new ServiceResult(e)); } ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check diagnostics. if (diagnosticInfos != null && diagnosticInfos.Count > 0) { Log("Returned non-empty DiagnosticInfos array during Write."); return false; } // check results. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < nodesToWrite.Count; ii++) { WriteValue request = nodesToWrite[ii]; TestVariable variable = (TestVariable)request.Handle; if (results[ii] == StatusCodes.BadUserAccessDenied) { continue; } if (results[ii] == StatusCodes.BadNotWritable) { Log( "Write failed when writing a writeable value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } if (StatusCode.IsBad(results[ii])) { if (request.Value.StatusCode != StatusCodes.Good) { if (results[ii] != StatusCodes.BadWriteNotSupported) { Log( "Unexpected error when writing the StatusCode for a Value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } if (request.Value.SourceTimestamp != DateTime.MinValue || request.Value.ServerTimestamp != DateTime.MinValue) { if (results[ii] != StatusCodes.BadWriteNotSupported) { Log( "Unexpected error when writing the Timestamp for a Value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } if (results[ii] != StatusCodes.BadTypeMismatch && results[ii] != StatusCodes.BadOutOfRange) { Log( "Unexpected error when writing a valid value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = request.NodeId; nodeToRead.AttributeId = request.AttributeId; nodeToRead.IndexRange = request.IndexRange; nodeToRead.Handle = request.Handle; nodesToRead.Add(nodeToRead); } // skip read back on failed. if (!success) { return success; } // check if nothing more do to. if (nodesToRead.Count == 0) { return true; } requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; DataValueCollection values = new DataValueCollection(); try { Session.Read( requestHeader, 0, TimestampsToReturn.Both, nodesToRead, out values, out diagnosticInfos); } catch (System.ServiceModel.CommunicationException e) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } catch (System.Xml.XmlException e) { Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } catch (ServiceResultException e) { if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return true; } throw new ServiceResultException(new ServiceResult(e)); } ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // check diagnostics. if (diagnosticInfos != null && diagnosticInfos.Count > 0) { Log("Returned non-empty DiagnosticInfos array during Read."); return false; } for (int ii = 0; ii < nodesToRead.Count; ii++) { ReadValueId request = nodesToRead[ii]; TestVariable variable = (TestVariable)request.Handle; DataValue valueWritten = variable.Values[variable.Values.Count-1]; if (StatusCode.IsBad(values[ii].StatusCode) && StatusCode.IsNotBad(valueWritten.StatusCode)) { Log( "Could not read back the value written '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.WrappedValue, values[ii].StatusCode); success = false; break; } Opc.Ua.Test.DataComparer comparer = new Opc.Ua.Test.DataComparer(Session.MessageContext); comparer.ThrowOnError = false; if (!comparer.CompareVariant(values[ii].WrappedValue, valueWritten.WrappedValue)) { Log( "Read back value does not match the value written '{0}'. NodeId = {1}, Value = {2}, ReadValue = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.WrappedValue, values[ii].WrappedValue); success = false; break; } if (valueWritten.StatusCode != StatusCodes.Good) { if (values[ii].StatusCode != valueWritten.StatusCode) { Log( "Read back StatusCode does not match the StatusCode written '{0}'. NodeId = {1}, StatusCode = {2}, ReadStatusCode = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.StatusCode, values[ii].StatusCode); success = false; break; } } if (valueWritten.SourceTimestamp != DateTime.MinValue) { if (values[ii].SourceTimestamp != valueWritten.SourceTimestamp) { Log( "Read back ServerTimestamp does not match the ServerTimestamp written '{0}'. NodeId = {1}, Timestamp = {2}, ReadTimestamp = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.SourceTimestamp, values[ii].SourceTimestamp); success = false; break; } } } return success; }
/// <summary> /// Reads an DataValue array from the stream. /// </summary> public DataValueCollection ReadDataValueArray(string fieldName) { var values = new DataValueCollection(); List<object> token = null; if (!ReadArrayField(fieldName, out token)) { return values; } for (int ii = 0; ii < token.Count; ii++) { try { m_stack.Push(token[ii]); var element = ReadDataValue(null); values.Add(element); } finally { m_stack.Pop(); } } return values; }
/// <summary> /// Reads an DataValue array from the stream. /// </summary> public DataValueCollection ReadDataValueArray(string fieldName) { bool isNil = false; DataValueCollection values = new DataValueCollection(); if (BeginField(fieldName, true, out isNil)) { PushNamespace(Namespaces.OpcUaXsd); while (MoveToElement("DataValue")) { values.Add(ReadDataValue("DataValue")); } // check the length. if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count) { throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded); } PopNamespace(); EndField(fieldName); return values; } if (isNil) { return null; } return values; }
/// <summary> /// Samples the values of the items. /// </summary> private void DoSample(object state) { try { List<ISampledDataChangeMonitoredItem> items = state as List<ISampledDataChangeMonitoredItem>; // read values for all enabled items. if (items != null && items.Count > 0) { ReadValueIdCollection itemsToRead = new ReadValueIdCollection(items.Count); DataValueCollection values = new DataValueCollection(items.Count); List<ServiceResult> errors = new List<ServiceResult>(items.Count); // allocate space for results. for (int ii = 0; ii < items.Count; ii++) { ReadValueId readValueId = items[ii].GetReadValueId(); readValueId.Processed = false; itemsToRead.Add(readValueId); values.Add(null); errors.Add(null); } OperationContext context = new OperationContext(m_session, m_diagnosticsMask); // read values. m_nodeManager.Read( context, 0, itemsToRead, values, errors); // update monitored items. for (int ii = 0; ii < items.Count; ii++) { if (values[ii] == null) { values[ii] = new DataValue(StatusCodes.BadInternalError, DateTime.UtcNow); } items[ii].QueueValue(values[ii], errors[ii]); } } } catch (Exception e) { Utils.Trace(e, "Server: Unexpected error sampling values."); } }
/// <summary> /// Updates the values with the current values read from the server. /// </summary> public void Read(params WriteValue[] nodesToWrite) { if (m_session == null) { throw new ServiceResultException(StatusCodes.BadNotConnected); } // build list of values to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); if (nodesToWrite == null || nodesToWrite.Length == 0) { foreach (DataGridViewRow row in ResultsDV.Rows) { DataRowView source = row.DataBoundItem as DataRowView; WriteValue value = (WriteValue)source.Row[0]; row.Selected = false; ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = value.NodeId; nodeToRead.AttributeId = value.AttributeId; nodeToRead.IndexRange = value.IndexRange; nodeToRead.Handle = value; nodesToRead.Add(nodeToRead); } } else { foreach (WriteValue value in nodesToWrite) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = value.NodeId; nodeToRead.AttributeId = value.AttributeId; nodeToRead.IndexRange = value.IndexRange; nodeToRead.Handle = value; nodesToRead.Add(nodeToRead); } } // read the values. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // add the results to the display. for (int ii = 0; ii < results.Count; ii++) { WriteValue nodeToWrite = nodesToRead[ii].Handle as WriteValue; DataRow row = nodeToWrite.Handle as DataRow; if (StatusCode.IsGood(results[ii].StatusCode)) { nodeToWrite.Value = results[ii]; UpdateRow(row, results[ii]); } } }
/// <summary> /// Reads an DataValue array from the stream. /// </summary> public DataValueCollection ReadDataValueArray(string fieldName) { int length = ReadArrayLength(); if (length == -1) { return null; } DataValueCollection values = new DataValueCollection(length); for (int ii = 0; ii < length; ii++) { values.Add(ReadDataValue(null)); } return values; }
/// <summary> /// Reads the history of attributes for Bucket Brigade.Int1. /// </summary> static void HistoryReadAttributes(Session session) { List <string> VariableBrowsePaths = new List <string>(); VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:Description"); VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:DataType"); VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:ITEMID"); // translate browse paths. IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder, VariableBrowsePaths.ToArray()); DiagnosticInfoCollection diagnosticInfos; ReadRawModifiedDetails readDetails = new ReadRawModifiedDetails(); readDetails.StartTime = DateTime.MinValue; readDetails.EndTime = DateTime.Now; readDetails.IsReadModified = false; readDetails.NumValuesPerNode = 100; readDetails.ReturnBounds = false; ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails); HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection(); for (int ii = 0; ii < nodeIds.Count; ii++) { HistoryReadValueId readValueId = new HistoryReadValueId(); readValueId.NodeId = nodeIds[ii].NodeId; readValueId.Processed = false; idCollection.Add(readValueId); } HistoryReadResultCollection historyReadResults; ResponseHeader responseHeader = session.HistoryRead(null, eo, TimestampsToReturn.Both, true, idCollection, out historyReadResults, out diagnosticInfos); // process results. for (int ii = 0; ii < historyReadResults.Count; ii++) { HistoryReadResult historyReadResult = historyReadResults[ii]; HistoryData historyData = null; DataValueCollection dataValues = null; if (historyReadResult.HistoryData != null) { historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData; dataValues = historyData.DataValues; } ServiceResult result = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader); Console.WriteLine("\nHistoryRead result code for {0}: {1}", VariableBrowsePaths[ii], result.StatusCode.ToString()); if (StatusCode.IsBad(historyReadResult.StatusCode)) { continue; } if (dataValues == null) { Console.WriteLine("dataValues == null"); continue; } for (int jj = 0; jj < dataValues.Count; jj++) { DataValue dataValue = dataValues[jj]; // write value. Console.WriteLine("\t{0}: V={1}", jj, dataValue.Value == null ? "null" : dataValue.Value.ToString()); Console.WriteLine("\t Q={0}, SrvT={1}, SrcT={2}\n", dataValue.StatusCode.ToString(), dataValue.ServerTimestamp, dataValue.SourceTimestamp); } } }
/// <summary> /// Reads a set of nodes /// </summary> public virtual void Read( OperationContext context, double maxAge, TimestampsToReturn timestampsToReturn, ReadValueIdCollection nodesToRead, out DataValueCollection values, out DiagnosticInfoCollection diagnosticInfos) { if (nodesToRead == null) throw new ArgumentNullException("nodesToRead"); if (maxAge < 0) { throw new ServiceResultException(StatusCodes.BadMaxAgeInvalid); } if (timestampsToReturn < TimestampsToReturn.Source || timestampsToReturn > TimestampsToReturn.Neither) { throw new ServiceResultException(StatusCodes.BadTimestampsToReturnInvalid); } bool diagnosticsExist = false; values = new DataValueCollection(nodesToRead.Count); diagnosticInfos = new DiagnosticInfoCollection(nodesToRead.Count); // create empty list of errors. List<ServiceResult> errors = new List<ServiceResult>(values.Count); for (int ii = 0; ii < nodesToRead.Count; ii++) { errors.Add(null); } // add placeholder for each result. bool validItems = false; Utils.Trace( (int)Utils.TraceMasks.ServiceDetail, "MasterNodeManager.Read - Count={0}", nodesToRead.Count); for (int ii = 0; ii < nodesToRead.Count; ii++) { DataValue value = null; DiagnosticInfo diagnosticInfo = null; // pre-validate and pre-parse parameter. errors[ii] = ReadValueId.Validate(nodesToRead[ii]); // return error status. if (ServiceResult.IsBad(errors[ii])) { nodesToRead[ii].Processed = true; } // found at least one valid item. else { nodesToRead[ii].Processed = false; validItems = true; } values.Add(value); diagnosticInfos.Add(diagnosticInfo); } // call each node manager. if (validItems) { for (int ii = 0; ii < m_nodeManagers.Count; ii++) { Utils.Trace( (int)Utils.TraceMasks.ServiceDetail, "MasterNodeManager.Read - Calling NodeManager {0} of {1}", ii, m_nodeManagers.Count); m_nodeManagers[ii].Read( context, maxAge, nodesToRead, values, errors); } } // process results. for (int ii = 0; ii < nodesToRead.Count; ii++) { DataValue value = values[ii]; // set an error code for nodes that were not handled by any node manager. if (!nodesToRead[ii].Processed) { value = values[ii] = new DataValue(StatusCodes.BadNodeIdUnknown, DateTime.UtcNow); errors[ii] = new ServiceResult(values[ii].StatusCode); } // update the diagnostic info and ensure the status code in the data value is the same as the error code. if (errors[ii] != null && errors[ii].Code != StatusCodes.Good) { if (value == null) { value = values[ii] = new DataValue(errors[ii].Code, DateTime.UtcNow); } value.StatusCode = errors[ii].Code; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]); diagnosticsExist = true; } } // apply the timestamp filters. if (timestampsToReturn != TimestampsToReturn.Server && timestampsToReturn != TimestampsToReturn.Both) { value.ServerTimestamp = DateTime.MinValue; } if (timestampsToReturn != TimestampsToReturn.Source && timestampsToReturn != TimestampsToReturn.Both) { value.SourceTimestamp = DateTime.MinValue; } } // clear the diagnostics array if no diagnostics requested or no errors occurred. UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos); }
static void HistoryReadProcessed(Session session) { // translate browse paths. IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder, VariableBrowsePaths.ToArray()); DiagnosticInfoCollection diagnosticInfos; NodeId aggregateNodeId = null; RequestHeader rh = null; ViewDescription vd = null; ReferenceDescriptionCollection references; byte[] cp; //Get the list of avalilable aggregate functions: session.Browse( rh, vd, Opc.Ua.ObjectIds.Server_ServerCapabilities_AggregateFunctions, 1000, BrowseDirection.Forward, ReferenceTypeIds.Aggregates, false, 0, out cp, out references); Console.WriteLine("{0} aggregates are detected:", references.Count); //Print the list of avalible aggregates: int i = 0; foreach (ReferenceDescription rd in references) { i++; Console.WriteLine("{0}. {1} {2}", i, rd.BrowseName, rd.NodeId.Identifier.ToString()); } //Select aggregate function: Console.WriteLine("\nEnter aggregate number: "); string str = Console.ReadLine(); i = System.Int16.Parse(str); if (i > 0 && i <= references.Count) { aggregateNodeId = ExpandedNodeId.ToNodeId(references[i - 1].NodeId, session.NamespaceUris); } //Prepare arguments to pass to read processed history ReadProcessedDetails readDetails = new ReadProcessedDetails(); readDetails.StartTime = new DateTime(2008, 1, 1, 12, 0, 0); readDetails.EndTime = new DateTime(2008, 1, 1, 12, 0, 12); readDetails.AggregateType = new NodeIdCollection(nodeIds.Count); for (int x = 0; x < nodeIds.Count; x++) { readDetails.AggregateType.Add(aggregateNodeId); } readDetails.ProcessingInterval = 500; //500 milliseconds ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails); HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection(); for (int ii = 0; ii < nodeIds.Count; ii++) { HistoryReadValueId readValueId = new HistoryReadValueId(); readValueId.NodeId = nodeIds[ii].NodeId; readValueId.Processed = true; idCollection.Add(readValueId); } HistoryReadResultCollection historyReadResults; //Read processed history: ResponseHeader responseHeader = session.HistoryRead(null, eo, TimestampsToReturn.Both, true, idCollection, out historyReadResults, out diagnosticInfos); //Print results: for (int ii = 0; ii < historyReadResults.Count; ii++) { HistoryReadResult historyReadResult = historyReadResults[ii]; ServiceResult result = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader); HistoryData historyData = null; DataValueCollection dataValues = null; if (!(historyReadResult.HistoryData == null)) { historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData; if (historyData == null) { dataValues = null; } else { dataValues = historyData.DataValues; } } Console.WriteLine("\nHistoryRead result code for {0}: {1}", VariableBrowsePaths[ii], result.StatusCode.ToString()); if (dataValues == null) { Console.WriteLine("dataValues == null"); continue; } for (int jj = 0; jj < dataValues.Count; jj++) { DataValue dataValue = dataValues[jj]; if (dataValue == null) { continue; } // write value. Console.WriteLine("{0}: V={1}, Q={2}, SrvT={3}, SrcT={4}", jj, dataValue.Value == null ? "null" : dataValue.Value.ToString(), dataValue.StatusCode.ToString(), dataValue.ServerTimestamp, dataValue.SourceTimestamp); } } }
/// <summary> /// Checks if a notification has arrived. Sends a publish if it has not. /// </summary> private void OnKeepAliveComplete(IAsyncResult result) { ReadValueIdCollection nodesToRead = (ReadValueIdCollection)result.AsyncState; AsyncRequestCompleted(result, 0, DataTypes.ReadRequest); try { // read the server status. DataValueCollection values = new DataValueCollection(); DiagnosticInfoCollection diagnosticInfos = new DiagnosticInfoCollection(); ResponseHeader responseHeader = EndRead( result, out values, out diagnosticInfos); ValidateResponse(values, nodesToRead); ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // validate value returned. ServiceResult error = ValidateDataValue(values[0], typeof(int), 0, diagnosticInfos, responseHeader); if (ServiceResult.IsBad(error)) { throw new ServiceResultException(error); } // send notification that keep alive completed. OnKeepAlive((ServerState)(int)values[0].Value, responseHeader.Timestamp); } catch (Exception e) { Utils.Trace("Unexpected keep alive error occurred: {0}", e.Message); } }
/// <summary> /// Updates the browse element with the properties return in the read results. /// </summary> /// <param name="typeTree">The type tree.</param> /// <param name="element">The element.</param> /// <param name="nodesToRead">The nodes to read.</param> /// <param name="values">The values.</param> /// <param name="nodeClass">The node class - passed only if all of the information in the ReferenceDescription is available.</param> /// <param name="onlyEssentialProperties">If true the only properties essential for browing were fetched.</param> /// <param name="first">The first.</param> /// <returns></returns> private bool UpdateBrowseElement( ITypeTable typeTree, BrowseElement element, ReadValueIdCollection nodesToRead, DataValueCollection values, NodeClass nodeClass, bool onlyEssentialProperties, int first) { // check for a valid range within the collection. if (first < 0 || first >= nodesToRead.Count) { return false; } if (nodeClass == NodeClass.Unspecified) { // verify node class. NodeClass actualNodeClass = (NodeClass)values[first++].GetValue<int>((int)NodeClass.Unspecified); if (actualNodeClass != NodeClass.Variable && actualNodeClass != NodeClass.Object) { return false; } element.NodeClass = actualNodeClass; // verify browse name. QualifiedName browseName = values[first++].GetValue<QualifiedName>(null); if (QualifiedName.IsNull(browseName)) { return false; } element.BrowseName = element.UaBrowseName = m_mapper.GetLocalBrowseName(browseName); // verify display name. LocalizedText displayName = values[first++].GetValue<LocalizedText>(null); if (LocalizedText.IsNullOrEmpty(displayName)) { return false; } element.BrowseName = displayName.Text; } if (!onlyEssentialProperties) { // check if long description exists. LocalizedText description = values[first++].GetValue<LocalizedText>(null); if (!LocalizedText.IsNullOrEmpty(description)) { element.UaDescription = description.Text; } else { element.UaDescription = ""; } } // update the masks. SetElementMasks(element); // nothing more to do. if (nodeClass == NodeClass.Object) { return true; } // verify data type. NodeId dataTypeId = values[first++].GetValue<NodeId>(null); if (dataTypeId == null && element.NodeClass == NodeClass.Variable) { return false; } int valueRank = values[first++].GetValue<int>(ValueRanks.Scalar); // update data type information. if (dataTypeId != null) { element.BuiltInType = DataTypes.GetBuiltInType(dataTypeId, typeTree); element.DataTypeId = m_mapper.GetLocalItemId(dataTypeId); element.ValueRank = valueRank; element.CanonicalDataType = (short)ComUtils.GetVarType(new TypeInfo(element.BuiltInType, element.ValueRank)); } if (!onlyEssentialProperties) { // update scan rate. element.ScanRate = (float)values[first++].GetValue<double>(MinimumSamplingIntervals.Indeterminate); // update access rights. byte userAccessLevel = values[first++].GetValue<byte>(0); if ((userAccessLevel & AccessLevels.CurrentRead) != 0) { element.AccessRights |= OpcRcw.Da.Constants.OPC_READABLE; } if ((userAccessLevel & AccessLevels.CurrentWrite) != 0) { element.AccessRights |= OpcRcw.Da.Constants.OPC_WRITEABLE; } if ((userAccessLevel & AccessLevels.HistoryRead) != 0) { element.IsHistoricalItem = true; } // cache the latest value. DataValue value = values[first++]; if (element.NodeClass == NodeClass.Variable) { element.LastValue = m_mapper.GetLocalDataValue(value); } // update HighEU and LowEU element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM; element.HighEU = Double.MaxValue; element.LowEU = Double.MaxValue; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EURange)) { Range euRange = values[first++].GetValue<Range>(null); if (euRange != null) { element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG; element.HighEU = euRange.High; element.LowEU = euRange.Low; } } // update HighIR and LowIR element.HighIR = Double.MaxValue; element.LowIR = Double.MaxValue; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.InstrumentRange)) { Range instrumentRange = values[first++].GetValue<Range>(null); if (instrumentRange != null) { element.HighIR = instrumentRange.High; element.LowIR = instrumentRange.Low; } } // update EngineeringUnits element.EngineeringUnits = null; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EngineeringUnits)) { EUInformation engineeringUnits = values[first++].GetValue<EUInformation>(null); if (engineeringUnits != null && engineeringUnits.DisplayName != null) { element.EngineeringUnits = engineeringUnits.DisplayName.Text; } } // update EUInfo element.EuInfo = null; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EnumStrings)) { LocalizedText[] enumStrings = values[first++].GetValue<LocalizedText[]>(null); if (enumStrings != null) { string[] strings = new string[enumStrings.Length]; for (int ii = 0; ii < enumStrings.Length; ii++) { if (enumStrings[ii] != null) { strings[ii] = enumStrings[ii].Text; } } element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED; element.EuInfo = strings; } } // update CloseLabel element.CloseLabel = null; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.TrueState)) { LocalizedText trueState = values[first++].GetValue<LocalizedText>(null); if (trueState != null) { element.CloseLabel = trueState.Text; } } // update OpenLabel element.OpenLabel = null; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.FalseState)) { LocalizedText falseState = values[first++].GetValue<LocalizedText>(null); if (falseState != null) { element.OpenLabel = falseState.Text; } } // update TimeZone element.TimeZone = Int32.MaxValue; if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.LocalTime)) { TimeZoneDataType timeZone = values[first++].GetValue<TimeZoneDataType>(null); if (timeZone != null) { element.TimeZone = timeZone.Offset; } } } return true; }
/// <summary> /// Reads the application description from the GDS. /// </summary> private ApplicationDescription Read(NodeId nodeId) { NamespaceTable wellKnownNamespaceUris = new NamespaceTable(); wellKnownNamespaceUris.Append(Namespaces.OpcUaGds); string[] browsePaths = new string[] { "1:ApplicationName", "1:ApplicationType", "1:ApplicationUri", "1:ProductUri", "1:GatewayServerUri", "1:DiscoveryUrls" }; List <NodeId> propertyIds = ClientUtils.TranslateBrowsePaths( ServerCTRL.Session, nodeId, wellKnownNamespaceUris, browsePaths); ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); foreach (NodeId propertyId in propertyIds) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = propertyId; nodeToRead.AttributeId = Attributes.Value; nodesToRead.Add(nodeToRead); } DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ServerCTRL.Session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); ApplicationDescription application = new ApplicationDescription(); application.ApplicationName = results[0].GetValue <LocalizedText>(null); application.ApplicationType = (ApplicationType)results[1].GetValue <int>((int)ApplicationType.Server); application.ApplicationUri = results[2].GetValue <string>(null); application.ProductUri = results[3].GetValue <string>(null); application.GatewayServerUri = results[4].GetValue <string>(null); string[] discoveryUrls = results[5].GetValue <string[]>(null); if (discoveryUrls != null) { application.DiscoveryUrls = new StringCollection(discoveryUrls); } return(application); }
/// <summary> /// 给PLC写数据 /// </summary> /// <param name="ordrNum">订单号</param> /// <param name="sncode">packid</param> /// <param name="ptcode">成品物料号</param> /// <param name="mozuCode"></param> /// <param name="mozusnnum"></param> /// <param name="keyValues">配方(key:Item value:配方值)</param> /// <returns></returns> public bool InitRequestData(string ordrNum, string sncode, string ptcode, string mozuCode, string mozusnnum, int canwork, int notwork, int ngmodel, int normalwork, int workfinish, int agluefinish, int bgluefinish, int planqty, Dictionary <string, byte[]> keyValues) { try { string ordnum = ".60,b,40"; //工单号地址 string prdcode = ".100,b,20"; //pack总成物料号 string snnum = ".120,b,70"; //产品sn号 string mzcode = ".190,b,20"; // 模组物料号 string mzsn = ".210,b,70"; //模组序列号--已经不写了 string canWorkItem = ".1,x4"; //可加工 string notWorkItem = ".1,x5"; //不可加工 string ngModelItem = ".2,x6"; //NG排出 string normalWorkItem = ".2,x7"; //正常加工 string workFinishItem = ".1,x7"; //当前工位加工完成 string aGlueFinishItem = ".3,x0"; //A扫码完成 string bGlueFinishItem = ".3,x1"; //B扫码完成 string formulaItem = keyValues.Keys.ToList()[0]; //配方的地址 string orderQtyItem = ".280,i"; //订单数量 string dbnum = MyStationModel.DataWriteDB; //写数据的DB块 NodeIdCollection writeNodecoll = new NodeIdCollection(); writeNodecoll.Add(new NodeId(dbnum + ordnum, ServerIndex)); //工单号 writeNodecoll.Add(new NodeId(dbnum + prdcode, ServerIndex)); //物料号 writeNodecoll.Add(new NodeId(dbnum + snnum, ServerIndex)); //packid writeNodecoll.Add(new NodeId(dbnum + mzcode, ServerIndex)); //模组物料号 writeNodecoll.Add(new NodeId(dbnum + mzsn, ServerIndex)); //模组物料号 writeNodecoll.Add(new NodeId(dbnum + canWorkItem, ServerIndex)); //可加工 writeNodecoll.Add(new NodeId(dbnum + notWorkItem, ServerIndex)); //不可加工 writeNodecoll.Add(new NodeId(dbnum + ngModelItem, ServerIndex)); //ng排料 writeNodecoll.Add(new NodeId(dbnum + normalWorkItem, ServerIndex)); //正常加工 writeNodecoll.Add(new NodeId(dbnum + workFinishItem, ServerIndex)); //本工位加工完成 writeNodecoll.Add(new NodeId(dbnum + aGlueFinishItem, ServerIndex)); //A扫码完成 writeNodecoll.Add(new NodeId(dbnum + bGlueFinishItem, ServerIndex)); //B扫码完成 writeNodecoll.Add(new NodeId(dbnum + formulaItem, ServerIndex)); //配方 writeNodecoll.Add(new NodeId(dbnum + orderQtyItem, ServerIndex)); //订单数量 DataValueCollection values = new DataValueCollection(); byte[] ordnumbuff = ConvertHelper.StringToByteArray(ordrNum, 40); byte[] ptcocebuff = ConvertHelper.StringToByteArray(ptcode, 20); byte[] sncodebuff = ConvertHelper.StringToByteArray(sncode, 70); byte[] mzcodebuff = ConvertHelper.StringToByteArray(mozuCode, 20); byte[] mzsnnumbuff = ConvertHelper.StringToByteArray(mozusnnum, 70); bool canworkValue = Convert.ToBoolean(canwork); bool notworkValue = Convert.ToBoolean(notwork); bool ngmodelValue = Convert.ToBoolean(ngmodel); bool normalVlue = Convert.ToBoolean(normalwork); bool workFinishValue = Convert.ToBoolean(workfinish); bool aGlueFinishValue = Convert.ToBoolean(agluefinish); bool bGlueFinishValue = Convert.ToBoolean(bgluefinish); byte[] formulaValue = keyValues[formulaItem];//配方值 short qty = (short)planqty; values.Add(new DataValue(ordnumbuff)); values.Add(new DataValue(ptcocebuff)); values.Add(new DataValue(sncodebuff)); values.Add(new DataValue(mzcodebuff)); values.Add(new DataValue(mzsnnumbuff)); values.Add(new DataValue(canworkValue)); values.Add(new DataValue(notworkValue)); values.Add(new DataValue(ngmodelValue)); values.Add(new DataValue(normalVlue)); values.Add(new DataValue(workFinishValue)); values.Add(new DataValue(aGlueFinishValue)); values.Add(new DataValue(bGlueFinishValue)); values.Add(new DataValue(formulaValue)); values.Add(new DataValue(qty));//数量 StatusCodeCollection resultCodes; MyServer.WriteValues(writeNodecoll, values, out resultCodes); foreach (StatusCode item in resultCodes) { if (StatusCode.IsBad(item.Code)) { return(false); } } return(true); } catch (Exception ex) { LogHelper.Write(ex, "system"); return(false); } }
/// <summary> /// Reads the arguments for the method. /// </summary> private void ReadArguments(NodeId nodeId) { m_inputArguments = null; m_outputArguments = null; // build list of references to browse. BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.NodeClassMask = (uint)NodeClass.Variable; nodeToBrowse.ResultMask = (uint)BrowseResultMask.BrowseName; nodesToBrowse.Add(nodeToBrowse); // find properties. ReferenceDescriptionCollection references = ClientUtils.Browse(m_session, null, nodesToBrowse, false); // build list of properties to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; references != null && ii < references.Count; ii++) { ReferenceDescription reference = references[ii]; // ignore out of server references. if (reference.NodeId.IsAbsolute) { continue; } // ignore other properties. if (reference.BrowseName != Opc.Ua.BrowseNames.InputArguments && reference.BrowseName != Opc.Ua.BrowseNames.OutputArguments) { continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = (NodeId)reference.NodeId; nodeToRead.AttributeId = Attributes.Value; nodeToRead.Handle = reference; nodesToRead.Add(nodeToRead); } // method has no arguments. if (nodesToRead.Count == 0) { return; } // read the arguments. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // save the results. for (int ii = 0; ii < results.Count; ii++) { ReferenceDescription reference = (ReferenceDescription)nodesToRead[ii].Handle; if (StatusCode.IsGood(results[ii].StatusCode)) { if (reference.BrowseName == Opc.Ua.BrowseNames.InputArguments) { m_inputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument)); } if (reference.BrowseName == Opc.Ua.BrowseNames.OutputArguments) { m_outputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument)); } } } // set default values for input arguments. if (m_inputArguments != null) { foreach (Argument argument in m_inputArguments) { argument.Value = TypeInfo.GetDefaultValue(argument.DataType, argument.ValueRank, m_session.TypeTree); } } }
/// <summary> /// Reads the values for the node attributes and returns a node object collection. /// Reads the nodeclass of the nodeIds, then reads /// the values for the node attributes and returns a node collection. /// </summary> /// <param name="nodeIds">The nodeId collection.</param> /// <param name="optionalAttributes">If optional attributes to read.</param> /// <param name="ct">The cancellation token.</param> public async Task <(IList <Node>, IList <ServiceResult>)> ReadNodesAsync( IList <NodeId> nodeIds, bool optionalAttributes = false, CancellationToken ct = default) { if (nodeIds.Count == 0) { return(new List <Node>(), new List <ServiceResult>()); } var nodeCollection = new NodeCollection(nodeIds.Count); var itemsToRead = new ReadValueIdCollection(nodeIds.Count); // first read only nodeclasses for nodes from server. itemsToRead = new ReadValueIdCollection( nodeIds.Select(nodeId => new ReadValueId { NodeId = nodeId, AttributeId = Attributes.NodeClass })); ReadResponse readResponse = await ReadAsync( null, 0, TimestampsToReturn.Neither, itemsToRead, ct).ConfigureAwait(false); DataValueCollection nodeClassValues = readResponse.Results; DiagnosticInfoCollection diagnosticInfos = readResponse.DiagnosticInfos; ClientBase.ValidateResponse(nodeClassValues, itemsToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead); // second determine attributes to read per nodeclass var attributesPerNodeId = new IDictionary <uint, DataValue> [nodeIds.Count].ToList(); var serviceResults = new ServiceResult[nodeIds.Count].ToList(); var attributesToRead = new ReadValueIdCollection(); CreateAttributesReadNodesRequest( readResponse.ResponseHeader, itemsToRead, nodeClassValues, diagnosticInfos, attributesToRead, attributesPerNodeId, nodeCollection, serviceResults, optionalAttributes); readResponse = await ReadAsync( null, 0, TimestampsToReturn.Neither, attributesToRead, ct).ConfigureAwait(false); DataValueCollection values = readResponse.Results; diagnosticInfos = readResponse.DiagnosticInfos; ClientBase.ValidateResponse(values, attributesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, attributesToRead); ProcessAttributesReadNodesResponse( readResponse.ResponseHeader, attributesToRead, attributesPerNodeId, values, diagnosticInfos, nodeCollection, serviceResults); return(nodeCollection, serviceResults); }
/// <summary> /// Validates the items by reading the attributes required to add them to the group. /// </summary> /// <param name="session">The session.</param> /// <param name="group">The group.</param> /// <param name="requests">The requests.</param> /// <param name="items">The items.</param> /// <param name="start">The start index.</param> /// <param name="count">The number of items to process.</param> private void ValidateItems( Session session, ComDaGroup group, ComDaCreateItemRequest[] requests, ComDaGroupItem[] items, int start, int count) { // build list of the UA attributes that need to be read. ReadValueIdCollection attributesToRead = new ReadValueIdCollection(); for (int ii = start; ii < start + count && ii < requests.Length; ii++) { // create the group item. ComDaCreateItemRequest request = requests[ii]; ComDaGroupItem item = items[ii] = new ComDaGroupItem(group, request.ItemId); item.NodeId = m_mapper.GetRemoteNodeId(request.ItemId); item.Active = request.Active; item.ClientHandle = request.ClientHandle; item.RequestedDataType = request.RequestedDataType; item.SamplingRate = -1; item.Deadband = -1; // add attributes. ReadValueId attributeToRead; attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.NodeClass; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.DataType; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.ValueRank; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.UserAccessLevel; attributesToRead.Add(attributeToRead); } // read attribute values from the server. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.Read( null, 0, TimestampsToReturn.Neither, attributesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, attributesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, attributesToRead); } catch (Exception e) { Utils.Trace(e, "Unexpected error reading attributes for items."); // set default values on error. for (int ii = start; ii < start + count && ii < requests.Length; ii++) { requests[ii].Error = ResultIds.E_INVALIDITEMID; } return; } // process results. int first = 0; for (int ii = start; ii < start + count && ii < requests.Length; ii++, first += 4) { ComDaGroupItem item = items[ii]; // verify node class. NodeClass nodeClass = (NodeClass)results[first].GetValue <int>((int)NodeClass.Unspecified); if (nodeClass != NodeClass.Variable) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // verify data type. NodeId dataTypeId = results[first + 1].GetValue <NodeId>(null); if (dataTypeId == null) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // get value rank. int valueRank = results[first + 2].GetValue <int>(ValueRanks.Scalar); // update datatypes. BuiltInType builtInType = DataTypes.GetBuiltInType(dataTypeId, session.TypeTree); item.RemoteDataType = new TypeInfo(builtInType, valueRank); item.CanonicalDataType = (short)ComUtils.GetVarType(item.RemoteDataType); // update access rights. byte userAccessLevel = results[first + 3].GetValue <byte>(0); if ((userAccessLevel & AccessLevels.CurrentRead) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_READABLE; } if ((userAccessLevel & AccessLevels.CurrentWrite) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_WRITEABLE; } } }
/// <summary> /// Handles the AfterSelect event of the BrowseTV control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.Forms.TreeViewEventArgs"/> instance containing the event data.</param> private void BrowseTV_AfterSelect(object sender, TreeViewEventArgs e) { try { EventFieldsLV.Items.Clear(); FilterDefinition filter = m_newFilter = new FilterDefinition(); filter.EventTypeId = null; filter.Fields = new List <FilterDefinitionField>(); if (e.Node == null) { OkBTN.Enabled = false; return; } OkBTN.Enabled = true; // get the currently selected event. NodeId eventTypeId = Opc.Ua.ObjectTypeIds.BaseEventType; ReferenceDescription reference = e.Node.Tag as ReferenceDescription; if (reference != null) { eventTypeId = (NodeId)reference.NodeId; } filter.EventTypeId = eventTypeId; // collect all of the fields defined for the event. SimpleAttributeOperandCollection fields = new SimpleAttributeOperandCollection(); List <NodeId> declarationIds = new List <NodeId>(); FormUtils.CollectFieldsForType(m_session, eventTypeId, fields, declarationIds); // need to read the description and datatype for each field. ReadValueIdCollection valuesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < declarationIds.Count; ii++) { ReadValueId valueToRead = new ReadValueId(); valueToRead.NodeId = declarationIds[ii]; valueToRead.AttributeId = Attributes.Description; valuesToRead.Add(valueToRead); valueToRead = new ReadValueId(); valueToRead.NodeId = declarationIds[ii]; valueToRead.AttributeId = Attributes.DataType; valuesToRead.Add(valueToRead); valueToRead = new ReadValueId(); valueToRead.NodeId = declarationIds[ii]; valueToRead.AttributeId = Attributes.ValueRank; valuesToRead.Add(valueToRead); } DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, valuesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead); // collect values. ignore errors since data used for display only. List <LocalizedText> descriptions = new List <LocalizedText>(); List <NodeId> datatypes = new List <NodeId>(); List <int> valueRanks = new List <int>(); for (int ii = 0; ii < declarationIds.Count * 3; ii += 3) { descriptions.Add(results[ii].GetValue <LocalizedText>(LocalizedText.Null)); datatypes.Add(results[ii + 1].GetValue <NodeId>(NodeId.Null)); valueRanks.Add(results[ii + 2].GetValue <int>(ValueRanks.Any)); } // populate the list box. for (int ii = 0; ii < fields.Count; ii++) { FilterDefinitionField field = new FilterDefinitionField(); filter.Fields.Add(field); field.Operand = fields[ii]; StringBuilder displayName = new StringBuilder(); for (int jj = 0; jj < field.Operand.BrowsePath.Count; jj++) { if (displayName.Length > 0) { displayName.Append('/'); } displayName.Append(field.Operand.BrowsePath[jj].Name); } field.DisplayName = displayName.ToString(); field.DataType = datatypes[ii]; field.ValueRank = valueRanks[ii]; field.BuiltInType = DataTypes.GetBuiltInType(field.DataType, m_session.TypeTree); field.Description = descriptions[ii].ToString(); // preserve previous settings. for (int jj = 0; jj < m_filter.Fields.Count; jj++) { if (m_filter.Fields[jj].DisplayName == field.DisplayName) { field.ShowColumn = m_filter.Fields[jj].ShowColumn; field.FilterValue = m_filter.Fields[jj].FilterValue; break; } } ListViewItem item = new ListViewItem(field.DisplayName); item.SubItems.Add(String.Empty); item.SubItems.Add(String.Empty); item.Checked = field.ShowColumn; item.Tag = field; INode dataType = m_session.NodeCache.Find(datatypes[ii]); if (dataType != null) { displayName = new StringBuilder(); displayName.Append(dataType.ToString()); if (valueRanks[ii] >= 0) { displayName.Append("[]"); } field.DataTypeDisplayName = displayName.ToString(); item.SubItems[1].Text = field.DataTypeDisplayName; } item.SubItems[2].Text = descriptions[ii].ToString(); EventFieldsLV.Items.Add(item); } // resize columns to fit text. for (int ii = 0; ii < EventFieldsLV.Columns.Count; ii++) { EventFieldsLV.Columns[ii].Width = -2; } } catch (Exception exception) { MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// 读取一个节点的所有属性 /// </summary> /// <param name="tag">节点值</param> /// <returns>所有的数据</returns> public DataValue[] ReadNoteDataValueAttributes(string tag) { NodeId sourceId = new NodeId(tag); ReadValueIdCollection nodesToRead = new ReadValueIdCollection( ); // attempt to read all possible attributes. // 尝试着去读取所有可能的特性 for (uint ii = Attributes.NodeId; ii <= Attributes.UserExecutable; ii++) { ReadValueId nodeToRead = new ReadValueId( ); nodeToRead.NodeId = sourceId; nodeToRead.AttributeId = ii; nodesToRead.Add(nodeToRead); } int startOfProperties = nodesToRead.Count; // find all of the pror of the node. BrowseDescription nodeToBrowse1 = new BrowseDescription( ); nodeToBrowse1.NodeId = sourceId; nodeToBrowse1.BrowseDirection = BrowseDirection.Forward; nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty; nodeToBrowse1.IncludeSubtypes = true; nodeToBrowse1.NodeClassMask = 0; nodeToBrowse1.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection( ); nodesToBrowse.Add(nodeToBrowse1); // fetch property references from the server. ReferenceDescriptionCollection references = FormUtils.Browse(m_session, nodesToBrowse, false); if (references == null) { return(new DataValue[0]); } for (int ii = 0; ii < references.Count; ii++) { // ignore external references. if (references[ii].NodeId.IsAbsolute) { continue; } ReadValueId nodeToRead = new ReadValueId( ); nodeToRead.NodeId = (NodeId)references[ii].NodeId; nodeToRead.AttributeId = Attributes.Value; nodesToRead.Add(nodeToRead); } // read all values. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); return(results.ToArray( )); }
/// <summary> /// Finds the targets for the specified reference. /// </summary> private static void UpdateInstanceDescriptions(Session session, List <InstanceDeclaration> instances, bool throwOnError) { try { ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < instances.Count; ii++) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.Description; nodesToRead.Add(nodeToRead); nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.DataType; nodesToRead.Add(nodeToRead); nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.ValueRank; nodesToRead.Add(nodeToRead); } // start the browse operation. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // update the instances. for (int ii = 0; ii < nodesToRead.Count; ii += 3) { InstanceDeclaration instance = instances[ii / 3]; instance.Description = results[ii].GetValue <LocalizedText>(LocalizedText.Null).Text; instance.DataType = results[ii + 1].GetValue <NodeId>(NodeId.Null); instance.ValueRank = results[ii + 2].GetValue <int>(ValueRanks.Any); if (!NodeId.IsNull(instance.DataType)) { instance.BuiltInType = DataTypes.GetBuiltInType(instance.DataType, session.TypeTree); instance.DataTypeDisplayText = session.NodeCache.GetDisplayText(instance.DataType); if (instance.ValueRank >= 0) { instance.DataTypeDisplayText += "[]"; } } } } catch (Exception exception) { if (throwOnError) { throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError); } } }
/// <summary> /// Insert annotations. /// </summary> private StatusCode InsertAnnotations( HdaItem item, DataValueCollection values, out int[] errors) { errors = null; string methodName = "IOPCHDA_SyncAnnotations.Insert"; int dwNumItems = values.Count; int[] phServer = new int[dwNumItems]; System.Runtime.InteropServices.ComTypes.FILETIME[] ftTimeStamps = new System.Runtime.InteropServices.ComTypes.FILETIME[dwNumItems]; OPCHDA_ANNOTATION[] pAnnotationValues = new OPCHDA_ANNOTATION[dwNumItems]; IntPtr ppErrors; try { for (int ii = 0; ii < dwNumItems; ii++) { DataValue value = values[ii]; phServer[ii] = item.ServerHandle; ftTimeStamps[ii] = ComUtils.GetFILETIME(value.SourceTimestamp); pAnnotationValues[ii] = new OPCHDA_ANNOTATION(); // pass an empty structure if the annotation is not valid. pAnnotationValues[ii].dwNumValues = 0; Annotation annotation = value.GetValue<Annotation>(null); if (annotation != null && !String.IsNullOrEmpty(annotation.Message)) { pAnnotationValues[ii].dwNumValues = 1; pAnnotationValues[ii].ftAnnotationTime = ComUtils.GetFILETIMEs(new DateTime[] { annotation.AnnotationTime }); pAnnotationValues[ii].ftTimeStamps = ComUtils.GetFILETIMEs(new DateTime[] { value.SourceTimestamp }); pAnnotationValues[ii].szAnnotation = ComUtils.GetUnicodeStrings(new string[] { annotation.Message }); pAnnotationValues[ii].szUser = ComUtils.GetUnicodeStrings(new string[] { annotation.UserName }); } } IOPCHDA_SyncAnnotations server = BeginComCall<IOPCHDA_SyncAnnotations>(methodName, true); server.Insert( dwNumItems, phServer, ftTimeStamps, pAnnotationValues, out ppErrors); // check for error. errors = ComUtils.GetInt32s(ref ppErrors, dwNumItems, true); // set bad type error for invalid annotations. for (int ii = 0; ii < dwNumItems; ii++) { if (pAnnotationValues[ii].dwNumValues == 0) { errors[ii] = ResultIds.E_BADTYPE; } } } catch (Exception e) { ComCallError(methodName, e); return StatusCodes.BadUnexpectedError; } finally { EndComCall(methodName); // free allocated memory. for (int ii = 0; ii < dwNumItems; ii++) { if (pAnnotationValues[ii].dwNumValues == 0) { continue; } IntPtr[] pointers = new IntPtr[1]; Marshal.Copy(pAnnotationValues[ii].szUser, pointers, 0, 1); Marshal.FreeCoTaskMem(pointers[0]); Marshal.Copy(pAnnotationValues[ii].szAnnotation, pointers, 0, 1); Marshal.FreeCoTaskMem(pointers[0]); Marshal.FreeCoTaskMem(pAnnotationValues[ii].ftAnnotationTime); Marshal.FreeCoTaskMem(pAnnotationValues[ii].ftTimeStamps); Marshal.FreeCoTaskMem(pAnnotationValues[ii].szUser); Marshal.FreeCoTaskMem(pAnnotationValues[ii].szAnnotation); } } return StatusCodes.Good; }
/// <summary> /// Invokes the Read service. /// </summary> public virtual ResponseHeader Read( RequestHeader requestHeader, double maxAge, TimestampsToReturn timestampsToReturn, ReadValueIdCollection nodesToRead, out DataValueCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Sends the read request to the server. /// </summary> /// <param name="session">The session.</param> /// <param name="nodesToRead">The nodes to read.</param> /// <returns></returns> private DataValueCollection Read(Session session, ReadValueIdCollection nodesToRead) { // read attribute values from the server. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.Read( null, 0, TimestampsToReturn.Source, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); } catch (Exception e) { // convert to item level errors. ServiceResult error = new ServiceResult(e, StatusCodes.BadUnexpectedError); results = new DataValueCollection(); for (int ii = 0; ii < nodesToRead.Count; ii++) { results.Add(new DataValue(error.StatusCode)); } } return results; }
/// <summary> /// Used by the performance test. /// </summary> public override ResponseHeader Read( RequestHeader requestHeader, double maxAge, TimestampsToReturn timestampsToReturn, ReadValueIdCollection nodesToRead, out DataValueCollection values, out DiagnosticInfoCollection diagnosticInfos) { if (requestHeader.ReturnDiagnostics != 5000) { return base.Read(requestHeader, maxAge, timestampsToReturn, nodesToRead, out values, out diagnosticInfos); } diagnosticInfos = null; DataValue value = new DataValue(); value.WrappedValue = new Variant((int)1); value.SourceTimestamp = DateTime.UtcNow; values = new DataValueCollection(nodesToRead.Count); foreach (ReadValueId valueId in nodesToRead) { values.Add(value); } return new ResponseHeader(); }
/// <summary> /// Sets the nodes in the control. /// </summary> public void Initialize( Session session, ReadValueIdCollection valueIds, DataValueCollection values, List<ServiceResult> results) { if (session == null) throw new ArgumentNullException("session"); Clear(); m_session = session; if (valueIds != null) { for (int ii = 0; ii < valueIds.Count; ii++) { ValueItem item = new ValueItem(); item.Node = m_session.NodeCache.Find(valueIds[ii].NodeId) as Node; item.AttributeId = valueIds[ii].AttributeId; if (values != null && ii < values.Count) { item.Value = values[ii]; } if (results != null && ii < results.Count) { item.Result = results[ii]; } AddItem(item, "DataType", -1); } } AdjustColumns(); }
/// <summary> /// Updates the EUInfo for the items. /// </summary> /// <param name="group">The group.</param> /// <param name="items">The items. Null entries are ignored.</param> public void UpdateItemEuInfo( ComDaGroup group, IList <ComDaGroupItem> items) { // get the session to use for the operation. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // build list of properties that need to be read. BrowsePathCollection browsePaths = new BrowsePathCollection(); for (int ii = 0; ii < items.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)items[ii]; // ignore invalid items or items which have already checked their EU type. if (item == null || item.EuType >= 0) { continue; } BrowsePath browsePath = new BrowsePath(); browsePath.StartingNode = item.NodeId; RelativePathElement element = new RelativePathElement(); element.ReferenceTypeId = ReferenceTypeIds.HasProperty; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = Opc.Ua.BrowseNames.EURange; browsePath.RelativePath.Elements.Add(element); browsePath.Handle = item; browsePaths.Add(browsePath); browsePath = new BrowsePath(); browsePath.StartingNode = item.NodeId; element = new RelativePathElement(); element.ReferenceTypeId = ReferenceTypeIds.HasProperty; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = Opc.Ua.BrowseNames.EnumStrings; browsePath.RelativePath.Elements.Add(element); browsePath.Handle = item; browsePaths.Add(browsePath); } // check if nothing to do. if (browsePaths.Count == 0) { return; } // translate browse paths. BrowsePathResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.TranslateBrowsePathsToNodeIds( null, browsePaths, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, browsePaths); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths); } catch (Exception) { for (int ii = 0; ii < browsePaths.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle; item.EuType = 0; } return; } // build list of properties that need to be read. ReadValueIdCollection propertiesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < results.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle; BrowsePathResult result = results[ii]; if (StatusCode.IsBad(result.StatusCode)) { if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM; } continue; } if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute) { if (item.EuType < 0) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM; } continue; } ReadValueId propertyToRead = new ReadValueId(); propertyToRead.NodeId = (NodeId)result.Targets[0].TargetId; propertyToRead.AttributeId = Attributes.Value; propertyToRead.Handle = item; propertiesToRead.Add(propertyToRead); if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG; } else { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED; } } // check if nothing to do. if (propertiesToRead.Count == 0) { return; } // read attribute values from the server. DataValueCollection values = null; try { session.Read( null, 0, TimestampsToReturn.Neither, propertiesToRead, out values, out diagnosticInfos); ClientBase.ValidateResponse(values, propertiesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead); } catch (Exception) { for (int ii = 0; ii < propertiesToRead.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle; item.EuType = 0; } return; } // process results. for (int ii = 0; ii < values.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle; if (StatusCode.IsBad(values[ii].StatusCode)) { item.EuType = 0; continue; } if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG) { Range range = (Range)values[ii].GetValue <Range>(null); if (range == null) { item.EuType = 0; continue; } item.EuInfo = new double[] { range.Low, range.High }; continue; } if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED) { LocalizedText[] texts = (LocalizedText[])values[ii].GetValue <LocalizedText[]>(null); if (texts == null) { item.EuType = 0; continue; } string[] strings = new string[texts.Length]; for (int jj = 0; jj < strings.Length; jj++) { if (!LocalizedText.IsNullOrEmpty(texts[jj])) { strings[jj] = texts[jj].Text; } } item.EuInfo = strings; continue; } } }
/// <summary> /// Reads the attributes for the node. /// </summary> private void ReadAttributes(NodeId nodeId) { // build list of attributes to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); foreach (uint attributeId in Attributes.GetIdentifiers()) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = nodeId; nodeToRead.AttributeId = attributeId; nodesToRead.Add(nodeToRead); } // read the attributes. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // add the results to the display. for (int ii = 0; ii < results.Count; ii++) { // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid) { continue; } } // add the metadata for the attribute. uint attributeId = nodesToRead[ii].AttributeId; ListViewItem item = new ListViewItem(Attributes.GetBrowseName(attributeId)); item.SubItems.Add(Attributes.GetBuiltInType(attributeId).ToString()); if (Attributes.GetValueRank(attributeId) >= 0) { item.SubItems[0].Text += "[]"; } // add the value. if (StatusCode.IsBad(results[ii].StatusCode)) { item.SubItems.Add(results[ii].StatusCode.ToString()); } else { item.SubItems.Add(ClientUtils.GetAttributeDisplayText(m_session, attributeId, results[ii].WrappedValue)); } item.Tag = results[ii]; // display in list. AttributesLV.Items.Add(item); } // set the column widths. for (int ii = 0; ii < AttributesLV.Columns.Count; ii++) { AttributesLV.Columns[ii].Width = -2; } }
/// <summary> /// 读取一个节点的所有属性 /// </summary> /// <param name="tag">节点信息</param> /// <returns>节点的特性值</returns> public OpcNodeAttribute[] ReadNoteAttributes(string tag) { NodeId sourceId = new NodeId(tag); ReadValueIdCollection nodesToRead = new ReadValueIdCollection( ); // attempt to read all possible attributes. // 尝试着去读取所有可能的特性 for (uint ii = Attributes.NodeClass; ii <= Attributes.UserExecutable; ii++) { ReadValueId nodeToRead = new ReadValueId( ); nodeToRead.NodeId = sourceId; nodeToRead.AttributeId = ii; nodesToRead.Add(nodeToRead); } int startOfProperties = nodesToRead.Count; // find all of the pror of the node. BrowseDescription nodeToBrowse1 = new BrowseDescription( ); nodeToBrowse1.NodeId = sourceId; nodeToBrowse1.BrowseDirection = BrowseDirection.Forward; nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty; nodeToBrowse1.IncludeSubtypes = true; nodeToBrowse1.NodeClassMask = 0; nodeToBrowse1.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection( ); nodesToBrowse.Add(nodeToBrowse1); // fetch property references from the server. ReferenceDescriptionCollection references = FormUtils.Browse(m_session, nodesToBrowse, false); if (references == null) { return(new OpcNodeAttribute[0]); } for (int ii = 0; ii < references.Count; ii++) { // ignore external references. if (references[ii].NodeId.IsAbsolute) { continue; } ReadValueId nodeToRead = new ReadValueId( ); nodeToRead.NodeId = (NodeId)references[ii].NodeId; nodeToRead.AttributeId = Attributes.Value; nodesToRead.Add(nodeToRead); } // read all values. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // process results. List <OpcNodeAttribute> nodeAttribute = new List <OpcNodeAttribute>( ); for (int ii = 0; ii < results.Count; ii++) { OpcNodeAttribute item = new OpcNodeAttribute( ); // process attribute value. if (ii < startOfProperties) { // ignore attributes which are invalid for the node. if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid) { continue; } // get the name of the attribute. item.Name = Attributes.GetBrowseName(nodesToRead[ii].AttributeId); // display any unexpected error. if (StatusCode.IsBad(results[ii].StatusCode)) { item.Type = Utils.Format("{0}", Attributes.GetDataTypeId(nodesToRead[ii].AttributeId)); item.Value = Utils.Format("{0}", results[ii].StatusCode); } // display the value. else { TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value); item.Type = typeInfo.BuiltInType.ToString( ); if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions) { item.Type += "[]"; } item.Value = results[ii].Value;//Utils.Format("{0}", results[ii].Value); } } // process property value. else { // ignore properties which are invalid for the node. if (results[ii].StatusCode == StatusCodes.BadNodeIdUnknown) { continue; } // get the name of the property. item.Name = Utils.Format("{0}", references[ii - startOfProperties]); // display any unexpected error. if (StatusCode.IsBad(results[ii].StatusCode)) { item.Type = String.Empty; item.Value = Utils.Format("{0}", results[ii].StatusCode); } // display the value. else { TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value); item.Type = typeInfo.BuiltInType.ToString( ); if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions) { item.Type += "[]"; } item.Value = results[ii].Value; //Utils.Format("{0}", results[ii].Value); } } nodeAttribute.Add(item); } return(nodeAttribute.ToArray( )); }
/// <summary> /// Reads the properties for the node. /// </summary> private void ReadProperties(NodeId nodeId) { // build list of references to browse. BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.NodeClassMask = (uint)NodeClass.Variable; nodeToBrowse.ResultMask = (uint)BrowseResultMask.All; nodesToBrowse.Add(nodeToBrowse); // find properties. ReferenceDescriptionCollection references = ClientUtils.Browse(m_session, View, nodesToBrowse, false); // build list of properties to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; references != null && ii < references.Count; ii++) { ReferenceDescription reference = references[ii]; // ignore out of server references. if (reference.NodeId.IsAbsolute) { continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = (NodeId)reference.NodeId; nodeToRead.AttributeId = Attributes.Value; nodeToRead.Handle = reference; nodesToRead.Add(nodeToRead); } if (nodesToRead.Count == 0) { return; } // read the properties. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // add the results to the display. for (int ii = 0; ii < results.Count; ii++) { ReferenceDescription reference = (ReferenceDescription)nodesToRead[ii].Handle; TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value); // add the metadata for the attribute. ListViewItem item = new ListViewItem(reference.ToString()); item.SubItems.Add(typeInfo.BuiltInType.ToString()); if (typeInfo.ValueRank >= 0) { item.SubItems[1].Text += "[]"; } // add the value. if (StatusCode.IsBad(results[ii].StatusCode)) { item.SubItems.Add(results[ii].StatusCode.ToString()); } else { item.SubItems.Add(results[ii].WrappedValue.ToString()); } item.Tag = results[ii]; // display in list. AttributesLV.Items.Add(item); } // set the column widths. for (int ii = 0; ii < AttributesLV.Columns.Count; ii++) { AttributesLV.Columns[ii].Width = -2; } }
/// <summary> /// Update data /// </summary> private StatusCode UpdateData( HdaItem item, PerformUpdateType updateType, DataValueCollection values, out int[] errors) { errors = null; string methodName = "IOPCHDA_SyncUpdate.Insert"; int dwNumItems = values.Count; int[] phServer = new int[dwNumItems]; System.Runtime.InteropServices.ComTypes.FILETIME[] ftTimeStamps = new System.Runtime.InteropServices.ComTypes.FILETIME[dwNumItems]; object[] vDataValues = new object[dwNumItems]; int[] pdwQualities = new int[dwNumItems]; for (int ii = 0; ii < dwNumItems; ii++) { DataValue value = values[ii]; phServer[ii] = item.ServerHandle; vDataValues[ii] = ComUtils.GetVARIANT(value.WrappedValue); pdwQualities[ii] = Utils.ToInt32(ComUtils.GetHdaQualityCode(value.StatusCode)); ftTimeStamps[ii] = ComUtils.GetFILETIME(value.SourceTimestamp); } IntPtr ppErrors = IntPtr.Zero; try { IOPCHDA_SyncUpdate server = BeginComCall<IOPCHDA_SyncUpdate>(methodName, true); switch (updateType) { case PerformUpdateType.Insert: { server.Insert( dwNumItems, phServer, ftTimeStamps, vDataValues, pdwQualities, out ppErrors); break; } case PerformUpdateType.Update: { server.InsertReplace( dwNumItems, phServer, ftTimeStamps, vDataValues, pdwQualities, out ppErrors); break; } case PerformUpdateType.Replace: { server.Replace( dwNumItems, phServer, ftTimeStamps, vDataValues, pdwQualities, out ppErrors); break; } } // check for error. errors = ComUtils.GetInt32s(ref ppErrors, dwNumItems, true); } catch (Exception e) { ComCallError(methodName, e); return StatusCodes.BadUnexpectedError; } finally { EndComCall(methodName); } return StatusCodes.Good; }
/// <summary> /// Reads the current values for the specified attributes. /// </summary> /// <param name="session">The session.</param> /// <param name="itemHandle">The item handle.</param> /// <param name="attributeIds">The attribute ids.</param> /// <returns></returns> public DaValue[] ReadCurrentValues(Session session, HdaItemHandle itemHandle, uint[] attributeIds) { DaValue[] results = new DaValue[attributeIds.Length]; // check handle. InternalHandle handle = itemHandle as InternalHandle; if (handle == null) { for (int ii = 0; ii < results.Length; ii++) { results[ii] = new DaValue(); results[ii].Error = ResultIds.E_INVALIDHANDLE; } return(results); } // look up the supported attributes for an item. ReadValueIdCollection supportedAttributes = handle.Item.SupportedAttributes; if (supportedAttributes == null) { handle.Item.SupportedAttributes = supportedAttributes = GetAvailableAttributes(session, handle.NodeId); } // build list of values to read. ReadValueIdCollection valuesToRead = new ReadValueIdCollection(); List <int> indexes = new List <int>(); for (int ii = 0; ii < attributeIds.Length; ii++) { ReadValueId valueToRead = GetReadValueId(supportedAttributes, attributeIds[ii]); if (valueToRead == null) { results[ii] = new DaValue(); results[ii].Error = ResultIds.E_INVALIDATTRID; continue; } valuesToRead.Add(valueToRead); indexes.Add(ii); // need to fetch the value rank as well. if (attributeIds[ii] == Constants.OPCHDA_DATA_TYPE) { valuesToRead.Add(GetReadValueId(supportedAttributes, ComHdaProxy.INTERNAL_ATTRIBUTE_VALUE_RANK)); indexes.Add(-1); } } // nothing to do. if (valuesToRead.Count == 0) { return(results); } // read values from the UA server. DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; session.Read( null, 0, TimestampsToReturn.Neither, valuesToRead, out values, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(values, valuesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead); // assign a local handle to all valid items. for (int ii = 0; ii < valuesToRead.Count; ii++) { int index = indexes[ii]; uint attributeId = (uint)valuesToRead[ii].Handle; // check for values which are combined with other values to create the value (e.g. ValueRank). if (index == -1) { continue; } results[index] = GetAttributeValue(session, attributeId, values, ii); // only support current value for now. if (results[index].Error == ResultIds.S_OK) { results[index].Error = ResultIds.S_CURRENTVALUE; } } return(results); }
/// <summary> /// Reads the attributes, verifies the results and updates the nodes. /// </summary> private bool Write(WriteValueCollection nodesToWrite) { bool success = true; StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; try { Session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); } catch (System.ServiceModel.CommunicationException e) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } catch (System.Xml.XmlException e) { Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } catch (ServiceResultException e) { if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } throw new ServiceResultException(new ServiceResult(e)); } ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check diagnostics. if (diagnosticInfos != null && diagnosticInfos.Count > 0) { Log("Returned non-empty DiagnosticInfos array during Write."); return(false); } // check results. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < nodesToWrite.Count; ii++) { WriteValue request = nodesToWrite[ii]; TestVariable variable = (TestVariable)request.Handle; if (results[ii] == StatusCodes.BadUserAccessDenied) { continue; } if (results[ii] == StatusCodes.BadNotWritable) { Log( "Write failed when writing a writeable value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } if (StatusCode.IsBad(results[ii])) { if (request.Value.StatusCode != StatusCodes.Good) { if (results[ii] != StatusCodes.BadWriteNotSupported) { Log( "Unexpected error when writing the StatusCode for a Value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } if (request.Value.SourceTimestamp != DateTime.MinValue || request.Value.ServerTimestamp != DateTime.MinValue) { if (results[ii] != StatusCodes.BadWriteNotSupported) { Log( "Unexpected error when writing the Timestamp for a Value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } if (results[ii] != StatusCodes.BadTypeMismatch && results[ii] != StatusCodes.BadOutOfRange) { Log( "Unexpected error when writing a valid value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = request.NodeId; nodeToRead.AttributeId = request.AttributeId; nodeToRead.IndexRange = request.IndexRange; nodeToRead.Handle = request.Handle; nodesToRead.Add(nodeToRead); } // skip read back on failed. if (!success) { return(success); } // check if nothing more do to. if (nodesToRead.Count == 0) { return(true); } requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; DataValueCollection values = new DataValueCollection(); try { Session.Read( requestHeader, 0, TimestampsToReturn.Both, nodesToRead, out values, out diagnosticInfos); } catch (System.ServiceModel.CommunicationException e) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } catch (System.Xml.XmlException e) { Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } catch (ServiceResultException e) { if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded) { Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message); return(true); } throw new ServiceResultException(new ServiceResult(e)); } ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // check diagnostics. if (diagnosticInfos != null && diagnosticInfos.Count > 0) { Log("Returned non-empty DiagnosticInfos array during Read."); return(false); } for (int ii = 0; ii < nodesToRead.Count; ii++) { ReadValueId request = nodesToRead[ii]; TestVariable variable = (TestVariable)request.Handle; DataValue valueWritten = variable.Values[variable.Values.Count - 1]; if (StatusCode.IsBad(values[ii].StatusCode) && StatusCode.IsNotBad(valueWritten.StatusCode)) { Log( "Could not read back the value written '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.WrappedValue, values[ii].StatusCode); success = false; break; } Opc.Ua.Test.DataComparer comparer = new Opc.Ua.Test.DataComparer(Session.MessageContext); comparer.ThrowOnError = false; if (!comparer.CompareVariant(values[ii].WrappedValue, valueWritten.WrappedValue)) { Log( "Read back value does not match the value written '{0}'. NodeId = {1}, Value = {2}, ReadValue = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.WrappedValue, values[ii].WrappedValue); success = false; break; } if (valueWritten.StatusCode != StatusCodes.Good) { if (values[ii].StatusCode != valueWritten.StatusCode) { Log( "Read back StatusCode does not match the StatusCode written '{0}'. NodeId = {1}, StatusCode = {2}, ReadStatusCode = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.StatusCode, values[ii].StatusCode); success = false; break; } } if (valueWritten.SourceTimestamp != DateTime.MinValue) { if (values[ii].SourceTimestamp != valueWritten.SourceTimestamp) { Log( "Read back ServerTimestamp does not match the ServerTimestamp written '{0}'. NodeId = {1}, Timestamp = {2}, ReadTimestamp = {3}", variable.Variable, variable.Variable.NodeId, valueWritten.SourceTimestamp, values[ii].SourceTimestamp); success = false; break; } } } return(success); }
/// <summary> /// Gets the item handles. /// </summary> /// <param name="session">The session.</param> /// <param name="itemIds">The item ids.</param> /// <param name="clientHandles">The client handles.</param> /// <param name="validateOnly">if set to <c>true</c> handles are not created and item ids are only validated.</param> /// <returns>The handles containing any error information.</returns> public HdaItemHandle[] GetItemHandles(Session session, string[] itemIds, int[] clientHandles, bool validateOnly) { HdaItemHandle[] handles = new HdaItemHandle[itemIds.Length]; ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < itemIds.Length; ii++) { InternalHandle handle = new InternalHandle(); handles[ii] = handle; if (clientHandles != null) { handle.ClientHandle = clientHandles[ii]; } string itemId = itemIds[ii]; if (String.IsNullOrEmpty(itemId)) { handle.Error = ResultIds.E_INVALIDITEMID; continue; } // check if item has already been assigned. Item item = null; if (!validateOnly) { lock (m_lock) { if (m_items.TryGetValue(itemId, out item)) { handle.NodeId = item.NodeId; handle.ServerHandle = ++m_lastServerHandle; handle.Item = item; item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); continue; } } } // create a new item. handle.Item = item = new Item(); item.ItemId = itemId; handle.Error = ResultIds.S_OK; // assume valid for no - set to an error when detected. handle.NodeId = item.NodeId = m_mapper.GetRemoteNodeId(itemId); nodesToRead.Add(Construct(handle, Attributes.UserAccessLevel)); nodesToRead.Add(Construct(handle, Attributes.DisplayName)); nodesToRead.Add(Construct(handle, Attributes.Description)); nodesToRead.Add(Construct(handle, Attributes.DataType)); nodesToRead.Add(Construct(handle, Attributes.ValueRank)); nodesToRead.Add(Construct(handle, Attributes.Historizing)); } // check if nothing to do. if (nodesToRead.Count == 0) { return(handles); } DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; // read values from the UA server. session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out values, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(values, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // assign a local handle to all valid items. NodeIdCollection nodesToRegister = new NodeIdCollection(); List <InternalHandle> items = new List <InternalHandle>(); for (int ii = 0; ii < nodesToRead.Count; ii++) { InternalHandle handle = (InternalHandle)nodesToRead[ii].Handle; DataValue value = values[ii]; Item item = handle.Item; // check status codes. if (StatusCode.IsBad(value.StatusCode)) { // description is an optional attribute. if (nodesToRead[ii].AttributeId != Attributes.Description) { handle.Error = ResultIds.E_UNKNOWNITEMID; } continue; } // check access level. if (nodesToRead[ii].AttributeId == Attributes.UserAccessLevel) { byte accessLevel = value.GetValue <byte>(AccessLevels.None); if ((accessLevel & AccessLevels.HistoryRead) == 0) { handle.Error = ResultIds.E_UNKNOWNITEMID; continue; } } // save attribute. switch (nodesToRead[ii].AttributeId) { case Attributes.DisplayName: { item.DisplayName = value.GetValue <LocalizedText>(null); break; } case Attributes.Description: { item.Description = value.GetValue <LocalizedText>(null); break; } case Attributes.DataType: { item.DataType = value.GetValue <NodeId>(null); break; } case Attributes.ValueRank: { item.ValueRank = value.GetValue <int>(ValueRanks.Scalar); break; } case Attributes.Historizing: { item.Historizing = value.GetValue <bool>(false); break; } } // should have all item metadata when processing the historizing attribute result. if (nodesToRead[ii].AttributeId == Attributes.Historizing) { // check for a fatal error with one or more mandatory attributes. if (handle.Error != ResultIds.S_OK) { continue; } BuiltInType builtInType = DataTypes.GetBuiltInType(item.DataType, session.TypeTree); item.RemoteType = new TypeInfo(builtInType, item.ValueRank); if (!validateOnly) { nodesToRegister.Add(item.NodeId); items.Add(handle); lock (m_lock) { m_items[handle.Item.ItemId] = handle.Item; handle.ServerHandle = ++m_lastServerHandle; handle.NodeId = handle.Item.NodeId; handle.Item.Refs++; m_handles[handle.ServerHandle] = handle; Utils.Trace("Created Handle: {0} {1}", handle.ServerHandle, handle.NodeId); } } } } return(handles); }