/// <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> /// Writes a value to a tag /// </summary> /// <param name="sTagID">Tag id</param> /// <param name="value">value of the tag</param> /// <returns></returns> private IResult WriteValue(string sTagID, object value) { try { ITag tag = GetTagByID(sTagID); if (tag == null) { return(new Result(false, new Exception("Could not find monitored tag !"))); } //Create collection WriteValueCollection writeValues = new WriteValueCollection(); //Create a write value and set it's properties WriteValue writeValue = new Opc.Ua.WriteValue(); writeValue.NodeId = new NodeId(sTagID); writeValue.AttributeId = Attributes.Value; // build and retrieve a Variant object for given tag Variant variant = GetVariantForTag(value, tag); //Set the writevalue datavalue writeValue.Value = new DataValue(variant); //add to the collection writeValues.Add(writeValue); StatusCodeCollection statusCodes; DiagnosticInfoCollection diagnosticInfo; // Do the Write Opreation ResponseHeader response = _session.Write(null, writeValues, out statusCodes, out diagnosticInfo); return(GetResultFromStatus(statusCodes)); } catch (Exception ex) { Logger.LogError(string.Format("Could not write value for tag {1} . Error : {0}", ex.Message, sTagID)); return(new Result(false, ex)); } }
/// <summary> /// Validates a write value parameter. /// </summary> public static ServiceResult Validate(WriteValue value) { // check for null structure. if (value == null) { return(StatusCodes.BadStructureMissing); } // null node ids are always invalid. if (value.NodeId == null) { return(StatusCodes.BadNodeIdInvalid); } // must be a legimate attribute value. if (!Attributes.IsValid(value.AttributeId)) { return(StatusCodes.BadAttributeIdInvalid); } // initialize as empty. value.ParsedIndexRange = NumericRange.Empty; // parse the index range if specified. if (!String.IsNullOrEmpty(value.IndexRange)) { try { value.ParsedIndexRange = NumericRange.Parse(value.IndexRange); } catch (Exception e) { return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty)); } // check that value provided is actually an array. Array array = value.Value.Value as Array; if (array == null) { return(StatusCodes.BadTypeMismatch); } NumericRange range = value.ParsedIndexRange; // check that the number of elements to write matches the index range. if (range.End >= 0 && (range.End - range.Begin != array.Length - 1)) { return(StatusCodes.BadIndexRangeNoData); } // check for single element. if (range.End < 0 && array.Length != 1) { return(StatusCodes.BadIndexRangeInvalid); } } else { value.ParsedIndexRange = NumericRange.Empty; } // passed basic validation. return(null); }
/// <summary> /// Validates a write value parameter. /// </summary> public static ServiceResult Validate(WriteValue value) { // check for null structure. if (value == null) { return(StatusCodes.BadStructureMissing); } // null node ids are always invalid. if (value.NodeId == null) { return(StatusCodes.BadNodeIdInvalid); } // must be a legimate attribute value. if (!Attributes.IsValid(value.AttributeId)) { return(StatusCodes.BadAttributeIdInvalid); } // initialize as empty. value.ParsedIndexRange = NumericRange.Empty; // parse the index range if specified. if (!String.IsNullOrEmpty(value.IndexRange)) { try { value.ParsedIndexRange = NumericRange.Parse(value.IndexRange); } catch (Exception e) { return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty)); } if (value.ParsedIndexRange.SubRanges != null) { Matrix matrix = value.Value.Value as Matrix; if (matrix == null) { // Check for String or ByteString arrays. Those DataTypes have special handling // when using sub ranges. bool isArrayWithValidDataType = value.Value.Value is Array && value.Value.WrappedValue.TypeInfo.BuiltInType == BuiltInType.String || value.Value.WrappedValue.TypeInfo.BuiltInType == BuiltInType.ByteString; if (!isArrayWithValidDataType) { return(StatusCodes.BadTypeMismatch); } } } else { // check that value provided is actually an array. Array array = value.Value.Value as Array; string str = value.Value.Value as string; if (array != null) { NumericRange range = value.ParsedIndexRange; // check that the number of elements to write matches the index range. if (range.End >= 0 && (range.End - range.Begin != array.Length - 1)) { return(StatusCodes.BadIndexRangeNoData); } // check for single element. if (range.End < 0 && array.Length != 1) { return(StatusCodes.BadIndexRangeInvalid); } } else if (str != null) { NumericRange range = value.ParsedIndexRange; // check that the number of elements to write matches the index range. if (range.End >= 0 && (range.End - range.Begin != str.Length - 1)) { return(StatusCodes.BadIndexRangeNoData); } // check for single element. if (range.End < 0 && str.Length != 1) { return(StatusCodes.BadIndexRangeInvalid); } } else { return(StatusCodes.BadTypeMismatch); } } } else { value.ParsedIndexRange = NumericRange.Empty; } // passed basic validation. return(null); }
/// <summary> /// Validates a write value parameter. /// </summary> public static ServiceResult Validate(WriteValue value) { // check for null structure. if (value == null) { return StatusCodes.BadStructureMissing; } // null node ids are always invalid. if (value.NodeId == null) { return StatusCodes.BadNodeIdInvalid; } // must be a legimate attribute value. if (!Attributes.IsValid(value.AttributeId)) { return StatusCodes.BadAttributeIdInvalid; } // initialize as empty. value.ParsedIndexRange = NumericRange.Empty; // parse the index range if specified. if (!String.IsNullOrEmpty(value.IndexRange)) { try { value.ParsedIndexRange = NumericRange.Parse(value.IndexRange); } catch (Exception e) { return ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty); } // check that value provided is actually an array. Array array = value.Value.Value as Array; if (array == null) { return StatusCodes.BadTypeMismatch; } NumericRange range = value.ParsedIndexRange; // check that the number of elements to write matches the index range. if (range.End >= 0 && (range.End - range.Begin != array.Length-1)) { return StatusCodes.BadIndexRangeInvalid; } // check for single element. if (range.End < 0 && array.Length != 1) { return StatusCodes.BadIndexRangeInvalid; } } else { value.ParsedIndexRange = NumericRange.Empty; } // passed basic validation. return null; }
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); } }
/// <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); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// #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> /// Creates a request to write a value to an external source. /// </summary> private ServiceResult AddWriteRequest(ISystemContext context, NodeHandle handle, WriteValue nodeToWrite, List<ReadWriteRequest> requests) { DataValue valueToWrite = nodeToWrite.Value; // cannot write status or timestamps to this source. if (valueToWrite.StatusCode != StatusCodes.Good || valueToWrite.ServerTimestamp != DateTime.MinValue || valueToWrite.SourceTimestamp != DateTime.MinValue) { return StatusCodes.BadWriteNotSupported; } // apply the index range (not supported by this external system). if (nodeToWrite.ParsedIndexRange != NumericRange.Empty) { return StatusCodes.BadIndexRangeInvalid; } // need node metadata to check data type. BaseVariableState variable = handle.Node as BaseVariableState; if (variable == null) { return StatusCodes.BadTypeMismatch; } // check that the data type is correct. TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType( valueToWrite.Value, variable.DataType, variable.ValueRank, Server.NamespaceUris, Server.TypeTree); if (typeInfo == null) { return StatusCodes.BadTypeMismatch; } requests.Add(new ReadWriteRequest() { Handle = handle, Value = valueToWrite.WrappedValue, UserIdentity = context.UserIdentity }); return ServiceResult.Good; }
private void NewMI_Click(object sender, EventArgs e) { try { WriteValue nodeToWrite = null; // choose the first selected row as a template. foreach (DataGridViewRow row in ResultsDV.SelectedRows) { DataRowView source = row.DataBoundItem as DataRowView; WriteValue value = (WriteValue)source.Row[0]; nodeToWrite = (WriteValue)value.Clone(); break; } if (nodeToWrite == null) { nodeToWrite = new WriteValue() { AttributeId = Attributes.Value }; } // prompt use to edit new value. WriteValue result = new EditWriteValueDlg().ShowDialog(m_session, nodeToWrite); if (result != null) { DataRow row = m_dataset.Tables[0].NewRow(); UpdateRow(row, result); m_dataset.Tables[0].Rows.Add(row); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Updates the row with the node to write. /// </summary> public void UpdateRow(DataRow row, WriteValue nodeToWrite) { row[0] = nodeToWrite; row[1] = ImageList.Images[ClientUtils.GetImageIndex(nodeToWrite.AttributeId, null)]; row[2] = (m_session != null) ? m_session.NodeCache.GetDisplayText(nodeToWrite.NodeId) : Utils.ToString(nodeToWrite.NodeId); row[3] = Attributes.GetBrowseName(nodeToWrite.AttributeId); row[4] = nodeToWrite.IndexRange; UpdateRow(row, nodeToWrite.Value); }
/// <summary> /// Prompts the user to edit the write request parameters for the set of nodes provided. /// </summary> public WriteValue ShowDialog(Session session, WriteValue nodeToWrite) { NodeBTN.Session = session; NodeBTN.SelectedReference = null; // fill in the control. NodeBTN.SelectedNode = nodeToWrite.NodeId; AttributeCB.SelectedIndex = (int)nodeToWrite.AttributeId - 1; IndexRangeTB.Text = nodeToWrite.IndexRange; ValueBTN.Value = nodeToWrite.Value.WrappedValue; if (nodeToWrite.Value.StatusCode != StatusCodes.Good) { StatusCodeTB.Text = (string)TypeInfo.Cast(nodeToWrite.Value.StatusCode, BuiltInType.String); StatusCodeCK.Checked = true; } if (nodeToWrite.Value.SourceTimestamp != DateTime.MinValue) { SourceTimestampTB.Text = (string)TypeInfo.Cast(nodeToWrite.Value.SourceTimestamp, BuiltInType.String); SourceTimestampCK.Checked = true; } if (nodeToWrite.Value.ServerTimestamp != DateTime.MinValue) { ServerTimestampTB.Text = (string)TypeInfo.Cast(nodeToWrite.Value.ServerTimestamp, BuiltInType.String); ServerTimestampCK.Checked = true; } if (base.ShowDialog() != DialogResult.OK) { return null; } // create the result. WriteValue result = new WriteValue(); result.NodeId = NodeBTN.SelectedNode; result.AttributeId = (uint)(AttributeCB.SelectedIndex + 1); result.ParsedIndexRange = NumericRange.Parse(IndexRangeTB.Text); result.Value.WrappedValue = ValueBTN.Value; if (StatusCodeCK.Checked) { result.Value.StatusCode = (StatusCode)TypeInfo.Cast(StatusCodeTB.Text, BuiltInType.StatusCode); } if (SourceTimestampCK.Checked) { result.Value.SourceTimestamp = (DateTime)TypeInfo.Cast(SourceTimestampTB.Text, BuiltInType.DateTime); } if (ServerTimestampCK.Checked) { result.Value.ServerTimestamp = (DateTime)TypeInfo.Cast(ServerTimestampTB.Text, BuiltInType.DateTime); } if (NumericRange.Empty != result.ParsedIndexRange) { result.IndexRange = result.ParsedIndexRange.ToString(); } else { result.IndexRange = String.Empty; } return result; }
/// <summary> /// Handles a write request. /// </summary> public List<ServiceResult> Write(List<WriteRequest> requests) { if (m_session == null) { throw new ServiceResultException(StatusCodes.BadCommunicationError); } WriteValueCollection valuesToWrite = new WriteValueCollection(); for (int ii = 0; ii < requests.Count; ii++) { WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = ExpandedNodeId.ToNodeId(requests[ii].RemoteId, m_session.NamespaceUris); valueToWrite.AttributeId = requests[ii].WriteValue.AttributeId; valueToWrite.IndexRange = requests[ii].WriteValue.IndexRange; valueToWrite.Value = requests[ii].WriteValue.Value; valuesToWrite.Add(valueToWrite); } StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); Session.ValidateResponse(results, valuesToWrite); Session.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); List<ServiceResult> errors = new List<ServiceResult>(); for (int ii = 0; ii < requests.Count; ii++) { if (results[ii] != StatusCodes.Good) { errors.Add(new ServiceResult(results[ii], ii, diagnosticInfos, responseHeader.StringTable)); } else { errors.Add(null); } } return errors; }