Example #1
0
        /// <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);
			}
		}
Example #2
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
		#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);
				}
			}
		}
Example #3
0
        /// <summary>
        /// Writes the values using the DA3 interfaces.
        /// </summary>
        /// <param name="requests">The requests.</param>
        private void Da30WriteItemValues(List<WriteRequest> requests)
        {
            int count = 0;
            string[] itemIDs = new string[requests.Count];
            OpcRcw.Da.OPCITEMVQT[] values = new OpcRcw.Da.OPCITEMVQT[requests.Count];
            WriteRequest[] writeRequests = new WriteRequest[requests.Count];

            for (int ii = 0; ii < requests.Count; ii++)
            {
                WriteRequest request = requests[ii];

                if (request == null)
                {
                    continue;
                }

                // convert to a DA compatible type.
                object convertedValue = null;
                request.Error = ComDaClientNodeManager.LocalToRemoteValue(request.Value.WrappedValue, out convertedValue);

                if (request.Error < 0)
                {
                    continue;
                }

                itemIDs[count] = request.ItemId;

                values[count].vDataValue = convertedValue;
                values[count].bQualitySpecified = 0;
                values[count].bTimeStampSpecified = 0;
                
                // check for quality.
                values[count].wQuality = ComUtils.GetQualityCode(request.Value.StatusCode);

                if (values[count].wQuality != Qualities.OPC_QUALITY_GOOD)
                {
                    values[count].bQualitySpecified = 1;
                }

                // check for server timestamp.
                if (request.Value.ServerTimestamp != DateTime.MinValue)
                {
                    values[count].ftTimeStamp = ComUtils.GetFILETIME(request.Value.ServerTimestamp);
                    values[count].bTimeStampSpecified = 1;
                }

                // ignore server timestamp if source timestamp is provided.
                if (request.Value.SourceTimestamp != DateTime.MinValue)
                {
                    values[count].ftTimeStamp = ComUtils.GetFILETIME(request.Value.SourceTimestamp);
                    values[count].bTimeStampSpecified = 1;
                }

                writeRequests[count] = request;
                count++;
            }

            IntPtr ppErrors = IntPtr.Zero;
            string methodName = "IOPCItemIO.WriteVQT";
            
            try
            {
                IOPCItemIO server = BeginComCall<IOPCItemIO>(methodName, true);
                
                server.WriteVQT(
                    count, 
                    itemIDs,
                    values, 
                    out ppErrors);
            }
            catch (Exception e)
            {
                ComUtils.TraceComError(e, methodName);
                return;
            }
            finally
            {
                EndComCall(methodName);
            }

            int[] errors = ComUtils.GetInt32s(ref ppErrors, count, true);
            
            for (int ii = 0; ii < count; ii++)
            {
                writeRequests[ii].Error = errors[ii];
            }
        }