/// <summary> /// Writes the value /// </summary> private Variant WriteValue(Session session, NodeId nodeId) { // cast the value to a string. object value = TypeInfo.Cast(ValueTB.Text, TypeInfo.Scalars.String, m_sourceType.BuiltInType); // build list of attributes to read. WriteValueCollection nodesToWrite = new WriteValueCollection(); WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = nodeId; nodeToWrite.AttributeId = Attributes.Value; // using the WrappedValue instead of the Value property because we know the TypeInfo. // this makes the assignment more efficient by avoiding reflection to determine type. nodeToWrite.Value.WrappedValue = new Variant(value, m_sourceType); nodesToWrite.Add(nodeToWrite); // override the diagnostic masks (other parameters are set to defaults). RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check status. if (StatusCode.IsBad(results[0])) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // return valid value. return nodeToWrite.Value.WrappedValue; }
private void ChangeLogFileBTN_Click(object sender, EventArgs e) { if (m_session == null) { return; } try { // want to get error text for this call. m_session.ReturnDiagnostics = DiagnosticsMasks.All; WriteValue value = new WriteValue(); value.NodeId = m_logFileNodeId; value.AttributeId = Attributes.Value; value.Value.Value = LogFilePathTB.Text; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(value); StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } finally { m_session.ReturnDiagnostics = DiagnosticsMasks.None; } }
/// <summary> /// Adds random values to write. /// </summary> private void AddWriteValues( TestVariable variable, WriteValueCollection nodesToWrite) { WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = variable.Variable.NodeId; nodeToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); value.Value = m_generator.GetRandom( variable.Variable.DataType, variable.Variable.ValueRank, variable.Variable.ArrayDimensions, Session.TypeTree); value.StatusCode = StatusCodes.Good; value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; variable.Values.Add(value); nodeToWrite.Value = value; nodeToWrite.Handle = variable; nodesToWrite.Add(nodeToWrite); }
public string WriteNode <T>(string writeNode, T writeData) { #region 写入内容 WriteValueCollection writeValues = new WriteValueCollection() { new WriteValue() { NodeId = writeNode, AttributeId = Attributes.Value, Value = new DataValue() { Value = writeData } } }; _session.Write( null, writeValues, out StatusCodeCollection wresults, out DiagnosticInfoCollection wdiagnosticInfos); foreach (var item in wresults) { Console.WriteLine("写入结果:" + item.ToString()); } return(wresults[0].ToString()); #endregion }
public async Task <bool> WriteNodeValueAsync(string serverUrl, VariableNode variableNode, VariableState state) { Session session = await GetSessionAsync(serverUrl); var typeManager = new DataTypeManager(session); WriteValueCollection writeValues = new WriteValueCollection(); WriteValue writeValue = new WriteValue { NodeId = variableNode.NodeId, AttributeId = Attributes.Value, Value = typeManager.GetDataValueFromVariableState(state, variableNode) }; writeValues.Add(writeValue); session.Write(null, writeValues, out var results, out _); if (!StatusCode.IsGood(results[0])) { if (results[0] == StatusCodes.BadTypeMismatch) { throw new ValueToWriteTypeException("Wrong Type Error: data sent are not of the type expected. Check your data and try again"); } throw new ValueToWriteTypeException(results[0].ToString()); } return(true); }
/// <summary> /// write a note to server(you should use try catch) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tag"></param> /// <param name="value"></param> /// <returns>if success True,otherwise False</returns> public bool WriteNode <T>(string tag, T value) { WriteValue valueToWrite = new WriteValue() { NodeId = new NodeId(tag), AttributeId = Attributes.Value }; valueToWrite.Value.Value = value; valueToWrite.Value.StatusCode = StatusCodes.Good; valueToWrite.Value.ServerTimestamp = DateTime.MinValue; valueToWrite.Value.SourceTimestamp = DateTime.MinValue; WriteValueCollection valuesToWrite = new WriteValueCollection { valueToWrite }; // 写入当前的值 m_session.Write( null, valuesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); return(!StatusCode.IsBad(results[0])); }
private void UpdateBTN_Click(object sender, EventArgs e) { try { WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = m_variableId; nodeToWrite.AttributeId = Attributes.Value; nodeToWrite.Value = new DataValue(); nodeToWrite.Value.WrappedValue = GetValue(); WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
public List <String> WriteVariable(string identifier, ushort namespaceIndex, Object value, uint attribute) { NodeId node = null; List <String> statusCodeWrite = new List <String>(); node = new NodeId(identifier, namespaceIndex); DataValue valueToWrite = new DataValue() { Value = (new Variant(value)) }; DiagnosticInfoCollection diagnosticInfos = null; WriteValueCollection nodesTowrite = new WriteValueCollection(); WriteValue nodeToWrite = new WriteValue() { NodeId = node, AttributeId = attribute, Value = valueToWrite, IndexRange = null }; nodesTowrite.Add(nodeToWrite); StatusCodeCollection writeResults; session.Write(null, nodesTowrite, out writeResults, out diagnosticInfos); for (int i = 0; i < writeResults.Count; i++) { statusCodeWrite.Add(writeResults[i].ToString()); } return(statusCodeWrite); }
private void WriteValue(Session session, NodeId variableId, DataValue value) { WriteValue nodeToWrite = new WriteValue { NodeId = variableId, AttributeId = Attributes.Value, Value = new DataValue { WrappedValue = value.WrappedValue } }; WriteValueCollection nodesToWrite = new WriteValueCollection { nodeToWrite }; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } }
// Original Features from the .NET Sample Client implementation, not needed for this OPC UA Client /* * public Tree GetRootNode(LabelViewModel textInfo) * { * ReferenceDescriptionCollection references; * Byte[] continuationPoint; * Tree browserTree = new Tree(); * * try * { * session.Browse( * null, * null, * ObjectIds.ObjectsFolder, * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out continuationPoint, * out references); * * browserTree.currentView.Add(new ListNode { id = ObjectIds.ObjectsFolder.ToString(), NodeName = "Root", children = (references?.Count != 0) }); * * return browserTree; * } * catch * { * Disconnect(session); * return null; * } * } * * public Tree GetChildren(string node) * { * ReferenceDescriptionCollection references; * Byte[] continuationPoint; * Tree browserTree = new Tree(); * * try * { * session.Browse( * null, * null, * node, * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out continuationPoint, * out references); * * if (references != null) * { * foreach (var nodeReference in references) * { * ReferenceDescriptionCollection childReferences = null; * Byte[] childContinuationPoint; * * session.Browse( * null, * null, * ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris), * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out childContinuationPoint, * out childReferences); * * INode currentNode = null; * try * { * currentNode = session.ReadNode(ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris)); * } * catch (Exception) * { * // skip this node * continue; * } * * byte currentNodeAccessLevel = 0; * byte currentNodeEventNotifier = 0; * bool currentNodeExecutable = false; * * VariableNode variableNode = currentNode as VariableNode; * if (variableNode != null) * { * currentNodeAccessLevel = variableNode.UserAccessLevel; * currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); * } * * ObjectNode objectNode = currentNode as ObjectNode; * if (objectNode != null) * { * currentNodeEventNotifier = objectNode.EventNotifier; * } * * ViewNode viewNode = currentNode as ViewNode; * if (viewNode != null) * { * currentNodeEventNotifier = viewNode.EventNotifier; * } * * MethodNode methodNode = currentNode as MethodNode; * if (methodNode != null) * { * currentNodeExecutable = methodNode.UserExecutable; * } * * browserTree.currentView.Add(new ListNode() * { * id = nodeReference.NodeId.ToString(), * NodeName = nodeReference.DisplayName.Text.ToString(), * nodeClass = nodeReference.NodeClass.ToString(), * accessLevel = currentNodeAccessLevel.ToString(), * eventNotifier = currentNodeEventNotifier.ToString(), * executable = currentNodeExecutable.ToString(), * children = (references?.Count != 0), * ImageUrl = (nodeReference.NodeClass.ToString() == "Variable") ? "folderOpen.jpg" : "folder.jpg" * }); * if (browserTree.currentView[0].ImageUrl == null) * { * browserTree.currentView[0].ImageUrl = ""; * } * } * if (browserTree.currentView.Count == 0) * { * INode currentNode = session.ReadNode(new NodeId(node)); * * byte currentNodeAccessLevel = 0; * byte currentNodeEventNotifier = 0; * bool currentNodeExecutable = false; * * VariableNode variableNode = currentNode as VariableNode; * * if (variableNode != null) * { * currentNodeAccessLevel = variableNode.UserAccessLevel; * currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); * } * * ObjectNode objectNode = currentNode as ObjectNode; * * if (objectNode != null) * { * currentNodeEventNotifier = objectNode.EventNotifier; * } * * ViewNode viewNode = currentNode as ViewNode; * * if (viewNode != null) * { * currentNodeEventNotifier = viewNode.EventNotifier; * } * * MethodNode methodNode = currentNode as MethodNode; * * if (methodNode != null ) * { * currentNodeExecutable = methodNode.UserExecutable; * } * * browserTree.currentView.Add(new ListNode() * { * id = node, * NodeName = currentNode.DisplayName.Text.ToString(), * nodeClass = currentNode.NodeClass.ToString(), * accessLevel = currentNodeAccessLevel.ToString(), * eventNotifier = currentNodeEventNotifier.ToString(), * executable = currentNodeExecutable.ToString(), * children = false, * ImageUrl = null * }); * } * } * return browserTree; * } * catch * { * Disconnect(session); * return null; * } * } */ #endregion #region custom VariableWrite Method /// <summary> /// Returns the ServiceResult from the ResponseHeader of the Variable Write Operation /// </summary> /// <param name="value">The int value that is to be written to the Node in the Server Namespace.</param> /// <param name="nodeId">The NodeId of the Node where the value shall be written.</param> public ResponseHeader VariableWrite(UInt16 value, string nodeId) { if (session != null) { if (session.Connected) { StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; // create a new WriteValueCollection (needed to call the Write Mehtod of the session) WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(new WriteValue { // NodeId of the Node to write NodeId = NodeId.Parse(nodeId), // We want to write the Value of the Node AttributeId = Attributes.Value, Value = new DataValue() { WrappedValue = value } }); // Actually write the Data. The method session.Write returns the responseHeader of the Write request response which is passed as the return value of this Method (VariableWrite) ResponseHeader responseHeader = session.Write(null, nodesToWrite, out results, out diagnosticInfos); return(responseHeader); } else { return(null); } } else { return(null); } }
private void CallBack_Write(IAsyncResult ar) { if (ar.IsCompleted) { TagItem tag = null; string tagServerIndex = string.Empty; DataValueCollection results; DiagnosticInfoCollection diagnosticinfos; WriteValueCollection tmpReadIds = ar.AsyncState as WriteValueCollection; ResponseHeader responseHeader = uAClient.Session.EndRead(ar, out results, out diagnosticinfos); ClientBase.ValidateResponse(results, tmpReadIds); ClientBase.ValidateDiagnosticInfos(diagnosticinfos, tmpReadIds); for (int i = 0; i < results.Count; i++) { tagServerIndex = tmpReadIds[i].NodeId.Identifier.ToString(); if (!_AsyncWriteTags.ContainsKey(tagServerIndex)) { continue; } tag = _AsyncWriteTags[tmpReadIds[i].NodeId.Identifier.ToString()]; tag.CBType = TagItem.CallBackType.AsyncRead; tag.Quality = results[i].StatusCode.ToString(); tag.Value = results[i].Value; tag.Timestamp = results[i].SourceTimestamp; tag.CallBack?.Invoke(tag); _AsyncWriteTags.Remove(tmpReadIds[i].NodeId.Identifier.ToString()); } } }
public static void Execute(IEnumerable <DataItem> OPCItems, Session session) { log.Info("Writing DataItem Values."); try { StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; WriteValueCollection valuesToWrite = CreateWriteValueCollection(OPCItems); session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw new ServiceResultException(results[0]); } } catch (Exception exception) { log.Error("OPC Error Writing Value", exception); } }
/// <summary> /// Sets the nodes in the control. /// </summary> public void Initialize( Session session, WriteValueCollection values, List <ServiceResult> results) { if (session == null) { throw new ArgumentNullException("session"); } Clear(); m_session = session; if (values != null) { for (int ii = 0; ii < values.Count; ii++) { ValueItem item = new ValueItem(); item.Node = m_session.NodeCache.Find(values[ii].NodeId) as Node; item.AttributeId = values[ii].AttributeId; item.Value = values[ii].Value; if (results != null && ii < results.Count) { item.Result = results[ii]; } AddItem(item, "DataType", -1); } } AdjustColumns(); }
/// <summary>write a note to server(you should use try catch)</summary> /// <typeparam name="T"></typeparam> /// <param name="tag"></param> /// <param name="value"></param> /// <returns>if success True,otherwise False</returns> public bool WriteNode <T>(string tag, T value) { WriteValue writeValue1 = new WriteValue() { NodeId = new NodeId(tag), AttributeId = 13 }; writeValue1.Value.Value = (object)value; writeValue1.Value.StatusCode = (StatusCode)0U; writeValue1.Value.ServerTimestamp = DateTime.MinValue; writeValue1.Value.SourceTimestamp = DateTime.MinValue; WriteValueCollection writeValueCollection = new WriteValueCollection(); WriteValue writeValue2 = writeValue1; writeValueCollection.Add(writeValue2); WriteValueCollection nodesToWrite = writeValueCollection; StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; this.m_session.Write((RequestHeader)null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse((IList)results, (IList)nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, (IList)nodesToWrite); return(!StatusCode.IsBad(results[0])); }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <returns></returns> public string VariableWrite(string node, int value) { try { StatusCodeCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; //WriteValueIdCollection nodesToRead = new WriteValueIdCollection(); WriteValueCollection nodesToWrite = new WriteValueCollection(); WriteValue valueId = new WriteValue(); valueId.NodeId = new NodeId(node); valueId.AttributeId = Attributes.Value; valueId.IndexRange = null; valueId.Value = new DataValue(value); nodesToWrite.Add(valueId); ResponseHeader response = session.Write(null, nodesToWrite, out values, out diagnosticInfos); /*string value = ""; * if (values[0].Value != null) * { * var rawValue = values[0].WrappedValue.ToString(); * value = rawValue.Replace("|", "\r\n").Replace("{", "").Replace("}", ""); * }*/ return(null); } catch { return(null); } }
private void OnNewValueToChannel(object sender, ValueToChannelArgs eventArgs) { var dataValue = Session.ReadValue(eventArgs.NodeId); dataValue.Value = eventArgs.Value; var writeValueCollection = new WriteValueCollection { new WriteValue { Value = new DataValue( new Variant(Convert.ChangeType(dataValue.Value, dataValue.Value.GetType()))), NodeId = eventArgs.NodeId, AttributeId = Attributes.Value } }; Session.Write(null, writeValueCollection, out var status, out _); foreach (var s in status) { if (s != StatusCodes.Good) { Logger.Info($"{eventArgs.NodeId}\t{s}"); } } }
/// <summary> /// write a note to server(you should use try catch) /// </summary> /// <typeparam name="T">The type of tag to write on</typeparam> /// <param name="tag">节点名称</param> /// <param name="value">值</param> /// <returns>if success True,otherwise False</returns> public bool WriteNode <T>(string tag, T value) { var valueToWrite = new WriteValue() { NodeId = new NodeId(tag), AttributeId = Attributes.Value }; valueToWrite.Value.Value = value; valueToWrite.Value.StatusCode = StatusCodes.Good; valueToWrite.Value.ServerTimestamp = DateTime.MinValue; valueToWrite.Value.SourceTimestamp = DateTime.MinValue; var valuesToWrite = new WriteValueCollection { valueToWrite }; // 写入当前的值 Session.Write( null, valuesToWrite, out var results, out var diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw new ServiceResultException(results[0]); } return(!StatusCode.IsBad(results[0])); }
private void WriteMI_Click(object sender, EventArgs e) { try { if (NodesTV.SelectedNode == null) { return; } ReferenceDescription reference = NodesTV.SelectedNode.Tag as ReferenceDescription; if (reference == null || (reference.NodeClass & (NodeClass.Variable | NodeClass.VariableType)) == 0) { return; } Session session = m_browser.Session; // build list of nodes to read. WriteValueCollection values = new WriteValueCollection(); WriteValue value = new WriteValue(); value.NodeId = (NodeId)reference.NodeId; value.AttributeId = Attributes.Value; value.IndexRange = null; value.Value = null; values.Add(value); // show form. new WriteDlg().Show(session, values); } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }
public static void write() { WriteValue value = new WriteValue(); value.NodeId = Data.tags["DigitConst"].NodeId; value.AttributeId = Attributes.Value; value.Value.Value = 10; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(value); StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } }
public bool WriteItem(object ValueToWrite) { if (ClientBound != null && ClientBound.IsConnected && ClientBound.IsAvailable && this.IsAvailable) { try { var MyValueCasted = Convert.ChangeType(ValueToWrite, TagType); DataValue val = new DataValue(); val.Value = MyValueCasted; List <WriteValue> nodesToWrite = new List <WriteValue>(); nodesToWrite.Add(new WriteValue() { NodeId = new NodeId(Address), AttributeId = Attributes.Value, Value = val }); WriteValueCollection nodesToWriteCollection = new WriteValueCollection(nodesToWrite); StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; ResponseHeader RS = ClientBound.ClientSession.Write( requestHeader, nodesToWriteCollection, out results, out diagnosticInfos); StatusCode code = results.First(); if (StatusCode.IsGood(code)) { Quality = TagQuality.GOOD; LastUpdate = DateTime.Now; return(true); } else { Quality = TagQuality.UNKNOWN; LastUpdate = DateTime.Now; ClientBound.Logger?.LogWarning($"OPC - Write Error on: {this.Name} @ {this.Address}. Reason: {code.ToString()}"); return(false); } } catch (Exception ex) { Quality = TagQuality.ERROR; ClientBound.Logger?.LogWarning($"OPC - Write Error on: {this.Name} @ {this.Address}. Ex: {ex.Message}"); return(false); } } else { Quality = TagQuality.DISCONNECTED; return(false); } }
public ResponseHeader CoreWrite(WriteValueCollection values, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(session.Write( null, values, out results, out diagnosticInfos)); }
/// <summary> /// Reads the attribute values from the server. /// </summary> /// <param name="valuesToWrite">The values to write.</param> /// <returns>The results.</returns> public int[] Write(WriteValueCollection valuesToWrite) { TraceState("Write", valuesToWrite.Count); // check for valid session. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } int masterError = ResultIds.E_FAIL; int[] errors = new int[valuesToWrite.Count]; if (session != null) { try { // write the values. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); // convert the response. for (int ii = 0; ii < results.Count; ii++) { errors[ii] = ComDaProxy.MapWriteStatusToErrorCode(valuesToWrite[ii].Value, results[ii]); } // return the results. return(errors); } catch (Exception e) { masterError = ComUtils.GetErrorCode(e, ResultIds.E_FAIL); } } // report any unexpected errors. for (int ii = 0; ii < errors.Length; ii++) { errors[ii] = masterError; } return(errors); }
public bool WriteValues(List <string> opcNodes, List <object> values, out List <bool> status) { bool ret = false; try { if (opcNodes.Count != values.Count) { throw new Exception("opcNodes.Count != values.Count"); } int count = opcNodes.Count; status = new List <bool>(count); List <Type> types = new List <Type>(count); List <NodeId> nodeIds = new List <NodeId>(count); DiagnosticInfoCollection diags; StatusCodeCollection statusCodes; WriteValueCollection writeValues = new WriteValueCollection(count); for (int i = 0; i < count; i++) { Variant variant = new Variant(values[i]); DataValue dataVal = new DataValue(variant); WriteValue writeVal = new WriteValue(); writeVal.Value = dataVal; writeVal.NodeId = new NodeId(opcNodes[i]); writeVal.AttributeId = Attributes.Value; writeValues.Add(writeVal); } ResponseHeader rh = session.Write(null, writeValues, out statusCodes, out diags); ret = StatusCode.IsGood(rh.ServiceResult.Code); for (int i = 0; i < count; i++) { //status[i] = StatusCode.IsGood(statusCodes[i]); status.Add(StatusCode.IsGood(statusCodes[i])); ret = ret & status[i]; } } catch (Exception ex) { ret = false; status = null; System.Diagnostics.Debug.WriteLine("Exception OpcUaClient::WriteValues " + ex.Message); } return(ret); }
public bool WriteNodes(List <string> NodeIds, List <string> Values) { var typeNodeIds = ReadNodes(NodeIds, Attributes.DataType); for (int i = 0; i < typeNodeIds.Count; i++) { if (!DataValue.IsGood(typeNodeIds[i])) { throw new ApplicationException("数据类型获取失败:" + NodeIds[i]); } } var builtinTypes = typeNodeIds.Select(typeNodeId => Opc.Ua.TypeInfo.GetBuiltInType(typeNodeId.Value as NodeId, m_session.TypeTree)).ToList(); var nodesToWrite = new WriteValueCollection(); for (int i = 0; i < NodeIds.Count; i++) { nodesToWrite.Add(new WriteValue() { NodeId = NodeIds[i], AttributeId = Attributes.Value, Value = new DataValue { Value = new Variant(Opc.Ua.TypeInfo.Cast(Values[i], builtinTypes[i])), StatusCode = StatusCodes.Good, ServerTimestamp = DateTime.MinValue, SourceTimestamp = DateTime.MinValue } }); } StatusCodeCollection results = new StatusCodeCollection(); DiagnosticInfoCollection diagnosticInfos = new DiagnosticInfoCollection(); m_session.Write( null, nodesToWrite, out results, out diagnosticInfos); //ClientBase.ValidateResponse(results, nodesToWrite); //ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); results.ForEach(x => { if (StatusCode.IsBad(x)) { throw new ServiceResultException(x); } }); return(true); }
/// <summary> /// Adds random values to write. /// </summary> private void AddWriteBadValues( TestVariable variable, WriteValueCollection nodesToWrite) { for (BuiltInType ii = BuiltInType.Null; ii < BuiltInType.DataValue; ii++) { if (variable.DataType != ii || variable.Variable.ValueRank >= 0) { // add random scalar. WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = variable.Variable.NodeId; nodeToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); value.Value = m_generator.GetRandom(ii); value.StatusCode = StatusCodes.Good; value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; variable.Values.Add(value); nodeToWrite.Value = value; nodeToWrite.Handle = variable; nodesToWrite.Add(nodeToWrite); } if (variable.DataType != ii || variable.Variable.ValueRank == ValueRanks.Scalar) { // add random array. WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = variable.Variable.NodeId; nodeToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); value.Value = m_generator.GetRandomArray(ii, true, 100, false); value.StatusCode = StatusCodes.Good; value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; variable.Values.Add(value); nodeToWrite.Value = value; nodeToWrite.Handle = variable; nodesToWrite.Add(nodeToWrite); } } }
public void Write <T>(string id, T value) { var wvq = new WriteValueCollection() { new WriteValue() { AttributeId = Opc.Ua.Attributes.Value, NodeId = new NodeId(id, NAMESPACE), Value = new DataValue(new Variant((T)value)) } }; session.Write(null, wvq, out StatusCodeCollection statusCodes, out DiagnosticInfoCollection diag); }
static async Task HandleSettingChanged(TwinCollection desiredProperties, object userContext) { string setting = "SetpointHeating"; if (desiredProperties.Contains(setting)) { BuildAcknowledgement(desiredProperties, setting); setpointHeating = (int)desiredProperties[setting]["value"]; greenMessage($"Heating Setpoint updated: {setpointHeating}"); // Write to OPC UA, Setpoint Temperature node try { WriteValue nodeToWrite = new WriteValue() { NodeId = SetpointHeatingNode, AttributeId = Attributes.Value, Value = new DataValue(setpointHeating) }; WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; // Write to setpoint temperature node ResponseHeader responseHeader = session.Write(null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // If no error, send the updated setpoint temperature to IoT Central. else if (StatusCode.IsGood(results[0])) { Console.WriteLine(session.ReadValue(SetpointHeatingNode).Value); await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperties); // Send an informational event to IoT Central eventInfoText = "Setpoint Heating has been updated: " + setpointHeating.ToString() + " °C"; } } catch (Exception ex) { Console.WriteLine("Exception message: " + ex.Message); } } }
/// <summary> /// Read Values of NodeIds, determine types, write back new random values. /// </summary> /// <param name="testSet">The nodeIds to modify.</param> private void UpdateValues(NodeId[] testSet) { // Read values var requestHeader = m_requestHeader; var nodesToRead = new ReadValueIdCollection(); foreach (NodeId nodeId in testSet) { nodesToRead.Add(new ReadValueId() { NodeId = nodeId, AttributeId = Attributes.Value }); } var response = m_server.Read(requestHeader, kMaxAge, TimestampsToReturn.Neither, nodesToRead, out var readDataValues, out var diagnosticInfos); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, readDataValues); Assert.AreEqual(testSet.Length, readDataValues.Count); var modifiedValues = new DataValueCollection(); foreach (var dataValue in readDataValues) { var typeInfo = TypeInfo.Construct(dataValue.Value); Assert.IsNotNull(typeInfo); var value = m_generator.GetRandom(typeInfo.BuiltInType); modifiedValues.Add(new DataValue() { WrappedValue = new Variant(value) }); } int ii = 0; var nodesToWrite = new WriteValueCollection(); foreach (NodeId nodeId in testSet) { nodesToWrite.Add(new WriteValue() { NodeId = nodeId, AttributeId = Attributes.Value, Value = modifiedValues[ii] }); ii++; } // Write Nodes requestHeader.Timestamp = DateTime.UtcNow; response = m_server.Write(requestHeader, nodesToWrite, out var writeDataValues, out diagnosticInfos); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, writeDataValues); }
async static Task Run() { UserIdentity userIdentity = new UserIdentity(new AnonymousIdentityToken()); ApplicationInstance application = new ApplicationInstance { ApplicationName = "UA Core Complex Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.ComplexClient" }; ApplicationConfiguration config = await application.LoadApplicationConfiguration("OpcConfig.xml", false).ConfigureAwait(false); var endpointURL = GetEnvVar("OPC_SERVER", "opc.tcp://localhost:62541/Quickstarts/ReferenceServer"); var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, false && !true, 15000); var m_session = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); WriteValueCollection nodesToWrite = new WriteValueCollection(); // Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32 WriteValue intWriteVal = new WriteValue(); intWriteVal.NodeId = new NodeId("ns=2;s=Tag_String"); intWriteVal.AttributeId = Attributes.Value; intWriteVal.Value = new DataValue(); intWriteVal.Value.Value = "Pierre-" + DateTime.Now.ToLongTimeString(); nodesToWrite.Add(intWriteVal); // Write the node attributes StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos; Console.WriteLine("Writing nodes..."); // Call Write Service m_session.Write(null, nodesToWrite, out results, out diagnosticInfos); // Validate the response ClientBase.ValidateResponse(results, nodesToWrite); // Display the results. Console.WriteLine("Write Results :"); foreach (StatusCode writeResult in results) { Console.WriteLine(" {0}", writeResult); } }
/// <summary> /// Displays the dialog. /// </summary> public void Show(Session session, WriteValueCollection values) { if (session == null) throw new ArgumentNullException("session"); m_session = session; BrowseCTRL.SetView(m_session, BrowseViewType.Objects, null); WriteValuesCTRL.Initialize(session, values); MoveBTN_Click(BackBTN, null); Show(); BringToFront(); }
private WriteValueCollection GetWriteValueCollection(Dictionary <string, ushort> valueDict) { var valueCollection = new WriteValueCollection(valueDict.Count); foreach (var item in valueDict) { var writevalue = new WriteValue(); writevalue.NodeId = new NodeId($"ns=2;{item.Key}"); writevalue.Value = new DataValue(new Variant(item.Value)); writevalue.AttributeId = Attributes.Value; valueCollection.Add(writevalue); } return(valueCollection); }
/// <summary> /// Invokes the Write service. /// </summary> public virtual ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return(CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported)); }
public bool WriteValue(WriteValuePayload payload) { // credits: https://github.com/OPCFoundation/UA-.NETStandard/issues/316 if (!payload.IsValid) { return(false); } try { var nodeToWrite = new WriteValue(); var expandedNodeId = ExpandedNodeId.Parse(payload.ExtendedNodeId); nodeToWrite.NodeId = GetNodeIdFromExpandedNodeId(expandedNodeId); nodeToWrite.AttributeId = Attributes.Value; nodeToWrite.Value.WrappedValue = "actual data"; var nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attribute StatusCodeCollection results = null; DiagnosticInfoCollection diagInfos = null; var responseHeader = OpcUaClientSession.Write( null, nodesToWrite, out results, out diagInfos ); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagInfos, nodesToWrite); // check for error if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagInfos, responseHeader.StringTable); } Trace($"Value written to {payload.ExtendedNodeId}"); } catch (Exception ex) { Trace($"An error occured when writing a value: {ex.Message}"); return(false); } return(true); }
/// <summary> /// Sets the nodes in the control. /// </summary> public void Initialize(Session session, WriteValueCollection values) { if (session == null) throw new ArgumentNullException("session"); Clear(); m_session = session; if (values != null) { foreach (WriteValue value in values) { AddItem(value); } } AdjustColumns(); }
public AsyncWriteTransaction(int transactionId, WriteValueCollection valuesToWrite) { TransactionId = transactionId; ValuesToWrite = valuesToWrite; }
/// <summary> /// Reads an verifies all of the nodes. /// </summary> private bool DoWriteBadTypeTest() { // follow tree from each starting node. bool success = true; // collection writeable variables that don't change during the test. List<TestVariable> variables = new List<TestVariable>(); for (int ii = 0; ii < WriteableVariables.Count; ii++) { TestVariable test = new TestVariable(); test.Variable = WriteableVariables[ii]; test.DataType = TypeInfo.GetBuiltInType(WriteableVariables[ii].DataType, Session.TypeTree); test.Values = new List<DataValue>(); variables.Add(test); } Log("Starting WriteBadTypeTest for {0} Nodes", variables.Count); double increment = MaxProgress/variables.Count; double position = 0; WriteValueCollection nodesToWrite = new WriteValueCollection(); int nodes = 0; int operations = 0; foreach (TestVariable variable in variables) { nodes++; AddWriteBadValues(variable, nodesToWrite); // process batch. if (nodesToWrite.Count > 100) { operations += nodesToWrite.Count; if (!WriteBadValues(nodesToWrite)) { success = false; break; } if (nodes > variables.Count/5) { Log("Wrote {0} attribute values for {1} nodes.", operations, nodes); nodes = 0; operations = 0; } nodesToWrite.Clear(); } position += increment; ReportProgress(position); } // process final batch. if (success) { if (nodesToWrite.Count > 0) { operations += nodesToWrite.Count; if (!WriteBadValues(nodesToWrite)) { success = false; } else { Log("Wrote {0} attribute values for {1} nodes.", operations, nodes); } nodesToWrite.Clear(); } } return success; }
/// <summary> /// Handles a write operation. /// </summary> protected override void Write( ServerSystemContext context, IList<WriteValue> nodesToWrite, IList<ServiceResult> errors, List<NodeHandle> nodesToValidate, IDictionary<NodeId, NodeState> cache) { WriteValueCollection requests = new WriteValueCollection(); List<int> indexes = new List<int>(); // validates the nodes and constructs requests for external nodes. for (int ii = 0; ii < nodesToValidate.Count; ii++) { WriteValue nodeToWrite = nodesToWrite[ii]; NodeHandle handle = nodesToValidate[ii]; lock (Lock) { // validate node. NodeState source = ValidateNode(context, handle, cache); if (source == null) { continue; } // determine if a local node. if (PredefinedNodes.ContainsKey(source.NodeId)) { // write the attribute value. errors[handle.Index] = source.WriteAttribute( context, nodeToWrite.AttributeId, nodeToWrite.ParsedIndexRange, nodeToWrite.Value); // updates to source finished - report changes to monitored items. source.ClearChangeMasks(context, false); } WriteValue request = (WriteValue)nodeToWrite.Clone(); request.NodeId = m_mapper.ToRemoteId(nodeToWrite.NodeId); request.Value.WrappedValue = m_mapper.ToRemoteVariant(nodeToWrite.Value.WrappedValue); requests.Add(request); indexes.Add(ii); } } // send request to external system. try { Opc.Ua.Client.Session client = GetClientSession(context); StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = client.Write( null, requests, out results, out diagnosticInfos); // these do sanity checks on the result - make sure response matched the request. ClientBase.ValidateResponse(results, requests); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, requests); // set results. for (int ii = 0; ii < requests.Count; ii++) { errors[indexes[ii]] = ServiceResult.Good; if (results[ii] != StatusCodes.Good) { errors[indexes[ii]] = new ServiceResult(results[ii], ii, diagnosticInfos, responseHeader.StringTable); } } } catch (Exception e) { // handle unexpected communication error. ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not access external system."); for (int ii = 0; ii < requests.Count; ii++) { errors[indexes[ii]] = error; } } }
/// <summary> /// Reads the attributes, verifies the results and updates the nodes. /// </summary> private bool WriteBadValues(WriteValueCollection nodesToWrite) { bool success = true; StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; 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; // allow access denied even if the node was theorectically writeable. 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; } TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType( request.Value.Value, variable.Variable.DataType, variable.Variable.ValueRank, Session.NamespaceUris, Session.TypeTree); if (typeInfo != null) { if (results[ii] != StatusCodes.Good && results[ii] != StatusCodes.BadTypeMismatch && results[ii] != StatusCodes.BadOutOfRange) { Log( "Unexpected error when writing a valid value for a Variable '{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 bad value for a Variable '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", variable.Variable, variable.Variable.NodeId, request.Value.WrappedValue, results[ii]); success = false; break; } } return success; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IOPCItemIO Members /// <summary> /// IOPCItemIO::WriteVQT - Writes one or more values, qualities and timestamps for the items specified. /// This is functionally similar to the IOPCSyncIO2::WriteVQT except that there is no associated group. /// </summary> public void WriteVQT( int dwCount, string[] pszItemIDs, OPCITEMVQT[] pItemVQT, out System.IntPtr ppErrors) { lock (m_lock) { if (m_session == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); // validate arguments. if (dwCount == 0 || pszItemIDs == null || pItemVQT == null || dwCount != pszItemIDs.Length || dwCount != pItemVQT.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } try { int[] errors = new int[dwCount]; // build list of values to write. WriteValueCollection valuesToWrite = new WriteValueCollection(); for (int ii = 0; ii < dwCount; ii++) { NodeId nodeId = ItemIdToNodeId(pszItemIDs[ii]); if (nodeId == null) { errors[ii] = ResultIds.E_INVALIDITEMID; continue; } VariableNode variable = m_session.NodeCache.Find(nodeId) as VariableNode; if (variable == null) { errors[ii] = ResultIds.E_UNKNOWNITEMID; continue; } WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = nodeId; valueToWrite.IndexRange = null; valueToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); int error = 0; value.Value = VariantValueToValue(variable, pItemVQT[ii].vDataValue, out error); if (error != ResultIds.S_OK) { errors[ii] = error; continue; } if (pItemVQT[ii].bQualitySpecified != 0) { value.StatusCode = ComUtils.GetQualityCode(pItemVQT[ii].wQuality); } if (pItemVQT[ii].bTimeStampSpecified != 0) { value.SourceTimestamp = ComUtils.GetDateTime(pItemVQT[ii].ftTimeStamp); } valueToWrite.Value = value; // needed to correlate results to input. valueToWrite.Handle = ii; valuesToWrite.Add(valueToWrite); } // write values from server. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; if (valuesToWrite.Count > 0) { m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); } for (int ii = 0; ii < valuesToWrite.Count; ii++) { // get index in original array. int index = (int)valuesToWrite[ii].Handle; // map UA code to DA code. errors[index] = MapWriteStatusToErrorCode(results[ii]); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { throw ComUtils.CreateComException(e); } } }
/// <summary> /// Reads the attribute values from the server. /// </summary> /// <param name="valuesToWrite">The values to write.</param> /// <returns>The results.</returns> public int[] Write(WriteValueCollection valuesToWrite) { TraceState("Write", valuesToWrite.Count); // check for valid session. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } int masterError = ResultIds.E_FAIL; int[] errors = new int[valuesToWrite.Count]; if (session != null) { try { // write the values. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); // convert the response. for (int ii = 0; ii < results.Count; ii++) { errors[ii] = ComDaProxy.MapWriteStatusToErrorCode(valuesToWrite[ii].Value, results[ii]); } // return the results. return errors; } catch (Exception e) { masterError = ComUtils.GetErrorCode(e, ResultIds.E_FAIL); } } // report any unexpected errors. for (int ii = 0; ii < errors.Length; ii++) { errors[ii] = masterError; } return errors; }
/// <summary> /// Invokes the Write service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="nodesToWrite">The list of Nodes, Attributes, and values to write.</param> /// <param name="results">The list of write result status codes for each write operation.</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { OperationContext context = ValidateRequest(requestHeader, RequestType.Write); try { if (nodesToWrite == null || nodesToWrite.Count == 0) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } m_serverInternal.NodeManager.Write( context, nodesToWrite, 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> /// Reads the attributes, verifies the results and updates the nodes. /// </summary> private bool Write(WriteValueCollection nodesToWrite) { bool success = true; StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; Session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); 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. for (int ii = 0; ii < nodesToWrite.Count; ii++) { WriteValue request = nodesToWrite[ii]; Node node = (Node)request.Handle; if (results[ii] == StatusCodes.BadNotWritable) { IVariable variable = node as IVariable; if (request.AttributeId == Attributes.Value && variable != null && ((variable.UserAccessLevel & AccessLevels.CurrentReadOrWrite) == AccessLevels.CurrentReadOrWrite)) { Log( "Write failed when writing a writeable value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}", node, node.NodeId, variable.Value, results[ii]); success = false; break; } if (Attributes.IsWriteable(request.AttributeId, node.UserWriteMask)) { Log( "Write failed when writing a writeable attribute '{0}'. NodeId = {1}, attribute = {2}, StatusCode = {3}", node, node.NodeId, Attributes.GetBrowseName(request.AttributeId), results[ii]); success = false; break; } continue; } if (results[ii] == StatusCodes.BadAttributeIdInvalid) { continue; } if (results[ii] == StatusCodes.BadUserAccessDenied) { continue; } if (results[ii] == StatusCodes.BadTypeMismatch || results[ii] == StatusCodes.BadOutOfRange) { if (request.Value.Value == null && request.IndexRange != null) { continue; } // unreadable values will have a status code for the locally cached value. if (request.Value.Value is StatusCode) { continue; } // allow for byte string and string values to have undocumented syntaxes. if (request.Value.Value is byte[] || request.Value.Value is string) { continue; } } if (StatusCode.IsBad(results[ii])) { if (request.IndexRange != null) { if (results[ii] == StatusCodes.BadWriteNotSupported || results[ii] == StatusCodes.BadIndexRangeInvalid || results[ii] == StatusCodes.BadIndexRangeNoData) { continue; } } if (request.Value.StatusCode != StatusCodes.Good) { if (results[ii] != StatusCodes.BadWriteNotSupported) { Log( "Unexpected error when writing the StatusCode for a Value '{0}'. NodeId = {1}, Attribute = {2}, Value = {3}, StatusCode = {4}", node, node.NodeId, Attributes.GetBrowseName(request.AttributeId), 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}, Attribute = {2}, Value = {3}, StatusCode = {4}", node, node.NodeId, Attributes.GetBrowseName(request.AttributeId), request.Value.WrappedValue, results[ii]); success = false; break; } continue; } Log( "Unexpected error when writing a valid Attribute '{0}'. NodeId = {1}, Attribute = {2}, Value = {3}, StatusCode = {4}", node, node.NodeId, Attributes.GetBrowseName(request.AttributeId), request.Value.WrappedValue, results[ii]); success = false; break; } } return success; }
/// <summary> /// IOPCSyncIO::Write - Writes values to one or more items in a group. /// </summary> public void Write( int dwCount, int[] phServer, object[] pItemValues, out System.IntPtr ppErrors) { // validate arguments. if (dwCount == 0 || phServer == null || pItemValues == null || dwCount != phServer.Length || dwCount != pItemValues.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } try { int[] errors = new int[dwCount]; // build list of values to write. WriteValueCollection valuesToWrite = new WriteValueCollection(); lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); for (int ii = 0; ii < dwCount; ii++) { Item itemToWrite = null; if (!m_items.TryGetValue(phServer[ii], out itemToWrite)) { errors[ii] = ResultIds.E_INVALIDHANDLE; continue; } VariableNode variable = itemToWrite.Variable; WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = variable.NodeId; valueToWrite.IndexRange = null; valueToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); int error = 0; value.Value = m_server.VariantValueToValue(variable, pItemValues[ii], out error); if (error != ResultIds.S_OK) { errors[ii] = error; continue; } valueToWrite.Value = value; // needed to correlate results to input. valueToWrite.Handle = ii; valuesToWrite.Add(valueToWrite); } } // write values from server. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; if (valuesToWrite.Count > 0) { m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); // validate response from the UA server. ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); //Utils.Trace( // "SyncWrite: GroupHandle={0}, ServerHandle={1}, Value={2}", // m_clientHandle, // phServer[0], // valuesToWrite[0].Value.WrappedValue); } for (int ii = 0; ii < valuesToWrite.Count; ii++) { // get index in original array. int index = (int)valuesToWrite[ii].Handle; // map UA code to DA code. errors[index] = Server.MapWriteStatusToErrorCode(results[ii]); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { Utils.Trace(e, "Error writing items."); throw ComUtils.CreateComException(e); } }
/// <summary> /// Begins an asynchronous invocation of the Write service. /// </summary> public IAsyncResult BeginWrite( RequestHeader requestHeader, WriteValueCollection nodesToWrite, AsyncCallback callback, object asyncState) { WriteRequest request = new WriteRequest(); request.RequestHeader = requestHeader; request.NodesToWrite = nodesToWrite; UpdateRequestHeader(request, requestHeader == null, "Write"); if (UseTransportChannel) { return TransportChannel.BeginSendRequest(request, callback, asyncState); } return InnerChannel.BeginWrite(new WriteMessage(request), callback, asyncState); }
/// <summary> /// Invokes the Write service. /// </summary> public virtual ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { WriteRequest request = new WriteRequest(); WriteResponse response = null; request.RequestHeader = requestHeader; request.NodesToWrite = nodesToWrite; UpdateRequestHeader(request, requestHeader == null, "Write"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (WriteResponse)genericResponse; } else { WriteResponseMessage responseMessage = InnerChannel.Write(new WriteMessage(request)); if (responseMessage == null || responseMessage.WriteResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.WriteResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "Write"); } return response.ResponseHeader; }
/// <summary> /// Sets the nodes in the control. /// </summary> public void Initialize( Session session, WriteValueCollection values, List<ServiceResult> results) { if (session == null) throw new ArgumentNullException("session"); Clear(); m_session = session; if (values != null) { for (int ii = 0; ii < values.Count; ii++) { ValueItem item = new ValueItem(); item.Node = m_session.NodeCache.Find(values[ii].NodeId) as Node; item.AttributeId = values[ii].AttributeId; item.Value = values[ii].Value; if (results != null && ii < results.Count) { item.Result = results[ii]; } AddItem(item, "DataType", -1); } } AdjustColumns(); }
/// <summary> /// Reads the values displayed in the control and moves to the display results state. /// </summary> public void Write() { if (m_session == null) { throw new ServiceResultException(StatusCodes.BadNotConnected); } // build list of values to write. WriteValueCollection nodesToWrite = new WriteValueCollection(); foreach (DataGridViewRow row in ResultsDV.Rows) { DataRowView source = row.DataBoundItem as DataRowView; WriteValue value = (WriteValue)source.Row[0]; row.Selected = false; nodesToWrite.Add(value); } // read the values. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Write( null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); IndexRangeCH.Visible = false; DataTypeCH.Visible = false; ValueCH.Visible = false; StatusCodeCH.Visible = false; ResultCH.Visible = true; // add the results to the display. for (int ii = 0; ii < results.Count; ii++) { DataRowView source = ResultsDV.Rows[ii].DataBoundItem as DataRowView; UpdateRow(source.Row, results[ii]); } }
/// <summary> /// Removes nodes that are not actually writeable. /// </summary> private void InitialWrite() { WriteValueCollection nodesToWrite = new WriteValueCollection(); lock (m_variables) { for (int ii = 0; ii < m_variables.Count; ii++) { TestVariable variable = m_variables[ii]; WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = variable.Variable.NodeId; nodeToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); if (!m_useDeadbandValues) { bool different = false; do { value.Value = m_generator.GetRandom( variable.Variable.DataType, variable.Variable.ValueRank, variable.Variable.ArrayDimensions, Session.TypeTree); if (variable.EURange != null) { value.Value = EnsureInRange(value.Value, variable.Variable, variable.EURange); } different = true; for (int jj = variable.Values.Count - 1; jj >= 0; jj--) { if (m_comparer.CompareVariant(value.WrappedValue, variable.Values[jj].WrappedValue)) { different = false; break; } if (variable.DataType == BuiltInType.Boolean) { break; } } } while (!different); } else { value.Value = IncrementValue(variable, m_deadbandCounter); } value.StatusCode = StatusCodes.Good; value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; nodeToWrite.Value = value; nodeToWrite.Handle = variable.Values.Count; nodesToWrite.Add(nodeToWrite); variable.Values.Add(value); variable.Timestamps.Add(DateTime.MinValue); } } StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; DateTime now = DateTime.UtcNow; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; // need to check if the test completes and the next one starts while the write is in progress. ResponseHeader responseHeader = Session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); 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; } // check results. lock (m_variables) { List<TestVariable> writeableVariables = new List<TestVariable>(); for (int ii = 0; ii < nodesToWrite.Count; ii++) { if (StatusCode.IsGood(results[ii])) { m_variables[ii].WriteError = false; writeableVariables.Add(m_variables[ii]); } } m_variables.Clear(); m_variables.AddRange(writeableVariables); } }
/// <summary> /// Performs n synchronous write operation. /// </summary> /// <param name="serverHandles">The server handles.</param> /// <param name="values">The values.</param> /// <returns>Any errors.</returns> public int[] SyncWrite(int[] serverHandles, DaValue[] values) { TraceState("SyncWrite", serverHandles.Length); ThrowIfDisposed(); int[] results = new int[serverHandles.Length]; WriteValueCollection valuesToWrite = new WriteValueCollection(); lock (m_lock) { // validate items. DaValue convertedValue = new DaValue(); for (int ii = 0; ii < serverHandles.Length; ii++) { ComDaGroupItem item = null; if (!m_itemsByHandle.TryGetValue(serverHandles[ii], out item)) { results[ii] = ResultIds.E_INVALIDHANDLE; continue; } // apply the COM type conversion. DaValue requestedValue = values[ii]; if (requestedValue.Value == null) { results[ii] = ResultIds.E_BADTYPE; continue; } if (item.CanonicalDataType != (short)VarEnum.VT_EMPTY) { object value = null; int error = ComUtils.ChangeTypeForCOM(requestedValue.Value, (VarEnum)item.CanonicalDataType, out value); if (error < 0) { results[ii] = error; continue; } // could happen if there is a problem reading the datatype from the server. if (requestedValue.Value == null) { results[ii] = ResultIds.E_BADTYPE; continue; } // copy all of the attributes into the converted value. convertedValue.Value = value; convertedValue.Quality = requestedValue.Quality; convertedValue.Timestamp = requestedValue.Timestamp; convertedValue.Error = requestedValue.Error; requestedValue = convertedValue; } WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = item.NodeId; valueToWrite.AttributeId = Attributes.Value; valueToWrite.Handle = ii; // convert value to UA data type. try { valueToWrite.Value = m_manager.Mapper.GetRemoteDataValue(requestedValue, item.RemoteDataType); } catch (Exception e) { results[ii] = ComUtils.GetErrorCode(e, ResultIds.E_BADTYPE); continue; } valuesToWrite.Add(valueToWrite); } } // check if nothing to do. if (valuesToWrite.Count == 0) { return results; } // write the values to the server. int[] remoteResults = m_manager.Write(valuesToWrite); // copy results. for (int ii = 0; ii < valuesToWrite.Count; ii++) { results[(int)valuesToWrite[ii].Handle] = remoteResults[ii]; } return results; }
/// <summary> /// Reads the attributes, verifies the results and updates the nodes. /// </summary> private bool Write(int counter) { bool success = true; m_deadbandCounter++; WriteValueCollection nodesToWrite = new WriteValueCollection(); lock (m_variables) { if (m_stopped != 0 || counter != m_writeTimerCounter) { return true; } for (int ii = 0; ii < m_variables.Count; ii++) { TestVariable variable = m_variables[ii]; WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = variable.Variable.NodeId; nodeToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); if (!m_useDeadbandValues) { bool different = false; do { value.Value = m_generator.GetRandom( variable.Variable.DataType, variable.Variable.ValueRank, variable.Variable.ArrayDimensions, Session.TypeTree); if (variable.EURange != null) { value.Value = EnsureInRange(value.Value, variable.Variable, variable.EURange); } different = true; for (int jj = variable.Values.Count-1; jj >= 0; jj--) { if (m_comparer.CompareVariant(value.WrappedValue, variable.Values[jj].WrappedValue)) { different = false; break; } if (variable.DataType == BuiltInType.Boolean) { break; } } } while (!different); } else { value.Value = IncrementValue(variable, m_deadbandCounter); } value.StatusCode = StatusCodes.Good; value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; nodeToWrite.Value = value; nodeToWrite.Handle = variable.Values.Count; nodesToWrite.Add(nodeToWrite); variable.Values.Add(value); variable.Timestamps.Add(DateTime.MinValue); } m_lastWriteTime = DateTime.UtcNow; } StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; DateTime now = DateTime.UtcNow; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; // need to check if the test completes and the next one starts while the write is in progress. ResponseHeader responseHeader = Session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); 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. lock (m_variables) { if (m_lastWriteTime > DateTime.MinValue && (DateTime.UtcNow - m_lastWriteTime).TotalMilliseconds > 300) { m_writeDelayed = true; Log("WARNING: A Write operation took {0}s. Test results may not be meaningful.", (DateTime.UtcNow - m_lastWriteTime).TotalSeconds); } m_lastWriteTime = DateTime.UtcNow; if (m_stopped != 0 || counter != m_writeTimerCounter) { return true; } for (int ii = 0; ii < nodesToWrite.Count; ii++) { TestVariable variable = m_variables[ii]; if (StatusCode.IsBad(results[ii])) { if (results[ii] == StatusCodes.BadTypeMismatch || results[ii] == StatusCodes.BadOutOfRange) { variable.WriteError = true; continue; } Log("Unexpected error during Write."); return false; } WriteValue request = nodesToWrite[ii]; variable.Timestamps[(int)request.Handle] = responseHeader.Timestamp; } m_writeCount++; } return success; }
/// <summary> /// Invokes the Write service. /// </summary> public virtual ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Parses the value and writes it to server. Closes the dialog if successful. /// </summary> private void OkBTN_Click(object sender, EventArgs e) { try { WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = m_nodeId; valueToWrite.AttributeId = m_attributeId; valueToWrite.Value.Value = ChangeType(); valueToWrite.Value.StatusCode = StatusCodes.Good; valueToWrite.Value.ServerTimestamp = DateTime.MinValue; valueToWrite.Value.SourceTimestamp = DateTime.MinValue; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(valueToWrite); // write current value. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw new ServiceResultException(results[0]); } DialogResult = DialogResult.OK; } catch (Exception exception) { ClientUtils.HandleException("Error Writing Value", exception); } }
/// <summary> /// IOPCAsyncIO3::WriteVQT - Writes one or more values, qualities and timestamps for the items specified. /// The results are returned via the client�s IOPCDataCallback connection established /// through the server�s IConnectionPointContainer. /// </summary> public void WriteVQT( int dwCount, int[] phServer, OPCITEMVQT[] pItemVQT, int dwTransactionID, out int pdwCancelID, out System.IntPtr ppErrors) { pdwCancelID = 0; // validate arguments. if (dwCount == 0 || phServer == null || pItemVQT == null || dwCount != phServer.Length || dwCount != pItemVQT.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } // get callback object - nothing more to do if missing. IOPCDataCallback callback = (IOPCDataCallback)GetCallback(typeof(IOPCDataCallback).GUID); if (callback == null) { throw ComUtils.CreateComException(ResultIds.CONNECT_E_NOCONNECTION); } try { int[] errors = new int[dwCount]; // build list of values to write. WriteValueCollection valuesToWrite = new WriteValueCollection(); lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); CallbackValue[] conversionErrors = null; for (int ii = 0; ii < dwCount; ii++) { Item itemToWrite = null; if (!m_items.TryGetValue(phServer[ii], out itemToWrite)) { errors[ii] = ResultIds.E_INVALIDHANDLE; continue; } VariableNode variable = itemToWrite.Variable; WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = variable.NodeId; valueToWrite.IndexRange = null; valueToWrite.AttributeId = Attributes.Value; DataValue value = new DataValue(); int error = 0; value.Value = m_server.VariantValueToValue(variable, pItemVQT[ii].vDataValue, out error); if (error != ResultIds.S_OK) { // only allocate this array when it is needed. if (conversionErrors == null) { conversionErrors = new CallbackValue[dwCount]; } // create the callback item. CallbackValue conversionError = new CallbackValue(); conversionError.ClientHandle = itemToWrite.ClientHandle; conversionError.Error = error; conversionErrors[ii] = conversionError; errors[ii] = error; continue; } valueToWrite.Value = value; if (pItemVQT[ii].bQualitySpecified != 0) { value.StatusCode = ComUtils.GetQualityCode(pItemVQT[ii].wQuality); } if (pItemVQT[ii].bTimeStampSpecified != 0) { value.SourceTimestamp = ComUtils.GetDateTime(pItemVQT[ii].ftTimeStamp); } // needed to correlate results to input. valueToWrite.Handle = itemToWrite; valuesToWrite.Add(valueToWrite); } // create transaction. if (valuesToWrite.Count > 0 || conversionErrors != null) { pdwCancelID = Utils.IncrementIdentifier(ref m_nextHandle); m_transactions[pdwCancelID] = new AsyncWriteTransaction(dwTransactionID, valuesToWrite); } // send conversion errors in the callback if no valid items available (CTT bug workaround). if (valuesToWrite.Count == 0 && conversionErrors != null) { // must return S_OK from this function if sending the errors in the callback. List<CallbackValue> errorsToSend = new List<CallbackValue>(); for (int ii = 0; ii < conversionErrors.Length; ii++) { if (conversionErrors[ii] != null) { errors[ii] = ResultIds.S_OK; errorsToSend.Add(conversionErrors[ii]); } } // queue the request. CallbackRequest request = new CallbackRequest(); request.CallbackType = CallbackType.Write; request.Callback = callback; request.TransactionId = dwTransactionID; request.GroupHandle = m_clientHandle; request.ServerHandle = m_serverHandle; request.Values = errorsToSend; QueueCallbackRequest(request); } } // write values from server. if (valuesToWrite.Count > 0) { m_session.BeginWrite( null, valuesToWrite, new AsyncCallback(OnWriteComplete), pdwCancelID); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { Utils.Trace(e, "Error writing items."); throw ComUtils.CreateComException(e); } }
/// <summary> /// Writes a set of values. /// </summary> public virtual void Write( OperationContext context, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (nodesToWrite == null) throw new ArgumentNullException("nodesToWrite"); int count = nodesToWrite.Count; bool diagnosticsExist = false; results = new StatusCodeCollection(count); diagnosticInfos = new DiagnosticInfoCollection(count); // add placeholder for each result. bool validItems = false; for (int ii = 0; ii < count; ii++) { StatusCode result = StatusCodes.Good; DiagnosticInfo diagnosticInfo = null; // pre-validate and pre-parse parameter. ServiceResult error = WriteValue.Validate(nodesToWrite[ii]); // return error status. if (ServiceResult.IsBad(error)) { nodesToWrite[ii].Processed = true; result = error.Code; // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error); diagnosticsExist = true; } } // found at least one valid item. else { nodesToWrite[ii].Processed = false; validItems = true; } results.Add(result); diagnosticInfos.Add(diagnosticInfo); } // call each node manager. if (validItems) { List<ServiceResult> errors = new List<ServiceResult>(count); errors.AddRange(new ServiceResult[count]); foreach (INodeManager nodeManager in m_nodeManagers) { nodeManager.Write( context, nodesToWrite, errors); } for (int ii = 0; ii < nodesToWrite.Count; ii++) { if (!nodesToWrite[ii].Processed) { errors[ii] = StatusCodes.BadNodeIdUnknown; } if (errors[ii] != null && errors[ii].Code != StatusCodes.Good) { results[ii] = errors[ii].Code; // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]); diagnosticsExist = true; } } ServerUtils.ReportWriteValue(nodesToWrite[ii].NodeId, nodesToWrite[ii].Value, results[ii]); } } // clear the diagnostics array if no diagnostics requested or no errors occurred. UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos); }
/// <summary> /// Writes the values for the specified item ids. /// </summary> /// <param name="itemIds">The item ids.</param> /// <param name="values">The values.</param> /// <returns>The results.</returns> public int[] Write(string[] itemIds, DaValue[] values) { int[] results = new int[itemIds.Length]; WriteValueCollection valuesToWrite = new WriteValueCollection(); ComDaReadPropertiesRequest[] requests = new ComDaReadPropertiesRequest[values.Length]; // prepare request. for (int ii = 0; ii < itemIds.Length; ii++) { ComDaReadPropertiesRequest request = requests[ii] = new ComDaReadPropertiesRequest(); request.ItemId = itemIds[ii]; } // need to get the data type of the remote node. m_browseManager.GetPropertyValues(Session, requests, PropertyIds.UaBuiltInType, PropertyIds.UaValueRank); // validate items. for (int ii = 0; ii < requests.Length; ii++) { ComDaReadPropertiesRequest request = requests[ii]; if (request.Error < 0) { results[ii] = request.Error; continue; } int? builtInType = request.Values[0].Value as int?; int? valueRank = request.Values[1].Value as int?; if (builtInType == null || valueRank == null) { results[ii] = ResultIds.E_UNKNOWNITEMID; continue; } // convert value to UA data type. WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = m_mapper.GetRemoteNodeId(itemIds[ii]); valueToWrite.AttributeId = Attributes.Value; valueToWrite.Handle = ii; // convert value to UA data type. try { TypeInfo remoteType = new TypeInfo((BuiltInType)builtInType.Value, valueRank.Value); valueToWrite.Value = m_mapper.GetRemoteDataValue(values[ii], remoteType); } catch (Exception e) { results[ii] = ComUtils.GetErrorCode(e, ResultIds.E_BADTYPE); continue; } valuesToWrite.Add(valueToWrite); } // check if nothing to do. if (valuesToWrite.Count == 0) { return results; } // write the values to the server. int[] remoteResults = m_groupManager.Write(valuesToWrite); // copy results. for (int ii = 0; ii < valuesToWrite.Count; ii++) { results[(int)valuesToWrite[ii].Handle] = remoteResults[ii]; } 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; }