Exemplo n.º 1
0
        /// <summary>
        /// Reads an array of FLOAT32, INT32, DOUBLE64 or ASCII (char) values form the device.
        /// The data length is given by the device.
        /// This method does only return when the device tells the host, that all data is read.
        /// The data is read in an loop with several sub queries.
        /// During this command is working, it is possible to use other commands with an different thread.
        /// </summary>
        /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
        /// <param name="parameterId">Device Parameter ID.</param>
        /// <param name="instance">Parameter Instance. (usually 1)</param>
        /// <param name="type">Specifies the type of the value to be read.</param>
        /// <param name="callback">Is called every time when the progress has changed.</param>
        /// <param name="expectedNrOfElements">Defines the expected number of elements to calculate the progress for the callback function.</param>
        /// <returns>Returned value.</returns>
        /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
        public dynamic GetBigData(byte?address, UInt16 parameterId, byte instance, MeParType type, ProgressUpdateCallback callback = null, int expectedNrOfElements = 0)
        {
            dynamic value;

            try
            {
                ushort       rcvElements;
                bool         hasMoreData;
                uint         totalReadElements = 0;
                MemoryStream totalStream       = new MemoryStream();

                do
                {
                    MeComPacket txFrame = new MeComPacket('#', address);
                    MeComVarConvert.AddString(txFrame.Payload, "?VB");
                    MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
                    MeComVarConvert.AddUint8(txFrame.Payload, instance);
                    MeComVarConvert.AddUint32(txFrame.Payload, totalReadElements); //Read start position
                    MeComVarConvert.AddUint16(txFrame.Payload, UInt16.MaxValue);   //Maximum Elements to read per call.

                    MeComPacket rxFrame = meQuerySet.Query(txFrame);
                    rcvElements        = MeComVarConvert.ReadUint16(rxFrame.Payload);
                    hasMoreData        = MeComVarConvert.ReadUint8(rxFrame.Payload) == 1;
                    totalReadElements += rcvElements;
                    if (rcvElements > 0)
                    {
                        rxFrame.Payload.CopyTo(totalStream);
                    }

                    callback?.Invoke(100.0 / expectedNrOfElements * totalReadElements);
                } while (hasMoreData);

                totalStream.Position = 0;

                callback?.Invoke(100);

                switch (type)
                {
                case MeParType.FLOAT32:
                    value = new float[totalReadElements];
                    break;

                case MeParType.INT32:
                    value = new int[totalReadElements];
                    break;

                case MeParType.DOUBLE64:
                    value = new double[totalReadElements];
                    break;

                case MeParType.LATIN1:
                    value = "";
                    break;

                case MeParType.BYTE:
                    value = new byte[totalReadElements];
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Unknown EParType: " + type);
                }

                for (int i = 0; i < totalReadElements; i++)
                {
                    switch (type)
                    {
                    case MeParType.FLOAT32:
                        value[i] = MeComVarConvert.ReadFloat32(totalStream);
                        break;

                    case MeParType.INT32:
                        value[i] = MeComVarConvert.ReadInt32(totalStream);
                        break;

                    case MeParType.DOUBLE64:
                        value[i] = MeComVarConvert.ReadDouble64(totalStream);
                        break;

                    case MeParType.LATIN1:
                        value = MeComVarConvert.ReadEncodedString(totalStream, (int)totalReadElements);
                        return(value);

                    case MeParType.BYTE:
                        value[i] = MeComVarConvert.ReadUint8(totalStream);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException("Unknown EParType: " + type);
                    }
                }
                return(value);
            }
            catch (Exception Ex)
            {
                throw new ComCommandException(String.Format("Get Value failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
            }
        }
Exemplo n.º 2
0
        private void DecodeFrame(ref MeComPacket RxFrame, byte c, ref MemoryStream LocalRxBuf)
        {
            try
            {
                if (c == Convert.ToByte('!'))
                {
                    //Start indicator
                    LocalRxBuf = new MemoryStream();
                    LocalRxBuf.WriteByte(c);
                }
                else
                {
                    if (c == 0x0D && (LocalRxBuf?.Length >= 11))
                    {
                        //End of Frame received
                        if (LocalRxBuf.Length == 11)
                        {
                            //ACK Received
                            LocalRxBuf.Position = 7;
                            ushort rcvCRC = MeComVarConvert.ReadUint16(LocalRxBuf);
                            if (rcvCRC == LastCRC)
                            {
                                //Valid Ack received --> Extract Data
                                LocalRxBuf.Position = 1;
                                RxFrame.Address     = MeComVarConvert.ReadUint8(LocalRxBuf);
                                RxFrame.SeqNr       = MeComVarConvert.ReadUint16(LocalRxBuf);
                                RxFrame.RcvType     = ERcvType.ACK;
                                statistics.IncRxFrames();
                            }
                        }
                        else
                        {
                            //Data Frame received
                            LocalRxBuf.Position = LocalRxBuf.Length - 4;
                            ushort rcvCRC = MeComVarConvert.ReadUint16(LocalRxBuf);

                            //Cut received CRC form stream and recalc CRC
                            LocalRxBuf.SetLength(LocalRxBuf.Length - 4);
                            ushort calcCRC = CalcCRC_CITT(LocalRxBuf);

                            if (calcCRC == rcvCRC)
                            {
                                LocalRxBuf.Position = 1;
                                RxFrame.Address     = MeComVarConvert.ReadUint8(LocalRxBuf);
                                RxFrame.SeqNr       = MeComVarConvert.ReadUint16(LocalRxBuf);
                                RxFrame.Payload     = new MemoryStream();
                                LocalRxBuf.CopyTo(RxFrame.Payload);
                                RxFrame.Payload.Position = 0; //Reset position for the user
                                RxFrame.RcvType          = ERcvType.Data;
                                statistics.IncRxFrames();
                            }
                            else
                            {
                                statistics.IncCrcErrors();
                            }
                        }
                    }
                    else
                    {
                        LocalRxBuf?.WriteByte(c);
                    }
                }
            }
            catch (ArgumentOutOfRangeException)
            {
                //Just ignore. They are thrown from MeComVarConvert
            }
        }