Пример #1
0
        /// <summary>
        /// Returns a FLOAT32, INT32 or DOUBLE64 value from the device.
        /// </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>
        /// <returns>Returned value.</returns>
        /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
        public dynamic GetValue(byte?address, UInt16 parameterId, byte instance, MeParType type)
        {
            try
            {
                MeComPacket txFrame = new MeComPacket('#', address);
                MeComVarConvert.AddString(txFrame.Payload, "?VR");
                MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
                MeComVarConvert.AddUint8(txFrame.Payload, instance);
                MeComPacket rxFrame = meQuerySet.Query(txFrame);

                switch (type)
                {
                case MeParType.FLOAT32:
                    return(MeComVarConvert.ReadFloat32(rxFrame.Payload));

                case MeParType.INT32:
                    return(MeComVarConvert.ReadInt32(rxFrame.Payload));

                case MeParType.DOUBLE64:
                    return(MeComVarConvert.ReadDouble64(rxFrame.Payload));

                default:
                    throw new ArgumentOutOfRangeException("Unknown Type. Received value: " + type);
                }
            }
            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);
            }
        }
Пример #2
0
 /// <summary>
 /// Returns the basic Meta data to the parameter.
 /// </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="min">Minimal value. Is always a double value.</param>
 /// <param name="max">Maximal value. Is always a double value.</param>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public void GetLimits(byte?address, ushort parameterId, byte instance, out double min, out double max)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "?VL");
         MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
         MeComVarConvert.AddUint8(txFrame.Payload, instance);
         MeComPacket rxFrame = meQuerySet.Query(txFrame);
         if (MeComVarConvert.ReadUint8(rxFrame.Payload) == 0)
         {
             //This is a float Value
             min = MeComVarConvert.ReadFloat32(rxFrame.Payload);
             max = MeComVarConvert.ReadFloat32(rxFrame.Payload);
         }
         else
         {
             //This is a INT32 Value
             min = MeComVarConvert.ReadInt32(rxFrame.Payload);
             max = MeComVarConvert.ReadInt32(rxFrame.Payload);
         }
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Get Limit Values failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
     }
 }
Пример #3
0
        /// <summary>
        /// Can download the file content of the Settings Dump file (*.mepar), which is created using the TEC Service Software.
        /// See Maintenance tab.
        /// Please read the TEC User Manual for further information about this feature.
        /// </summary>
        /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
        /// <param name="fileContent">Content of the .mepar file.</param>
        public void DownloadSettingsDumpFile(byte?address, string fileContent)
        {
            string[] settingsStrings = fileContent.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            if (settingsStrings.Length == 0)
            {
                throw new FormatException("The fileContent does not contain any settings strings!");
            }

            try
            {
                foreach (string settingsString in settingsStrings)
                {
                    MeComPacket txFrame = new MeComPacket('#', address);
                    MeComVarConvert.AddString(txFrame.Payload, "?SD");
                    MeComVarConvert.AddString(txFrame.Payload, settingsString);
                    MeComPacket rxFrame = meQuerySet.Query(txFrame);
                    if (MeComVarConvert.ReadUint4(rxFrame.Payload) != 0)
                    {
                        throw new InvalidOperationException("The settings string has not been accepted (CRC error)!");
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ComCommandException(String.Format("Download Settings File failed: Address: {0}, Detail: {1}", address, ex.Message), ex);
            }
        }
Пример #4
0
        /// <summary>
        /// Returns Meta data of the parameter.
        /// </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>
        /// <returns>Returned meta data object.</returns>
        /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
        public ParMetaData GetMetaData(byte?address, UInt16 parameterId, byte instance)
        {
            ParMetaData parMetaData = new ParMetaData();

            try
            {
                MeComPacket txFrame = new MeComPacket('#', address);
                MeComVarConvert.AddString(txFrame.Payload, "?VM");
                MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
                MeComVarConvert.AddUint8(txFrame.Payload, instance);
                MeComPacket rxFrame = meQuerySet.Query(txFrame);

                parMetaData.Type            = (MeParType)MeComVarConvert.ReadUint8(rxFrame.Payload);
                parMetaData.Flags           = (MeParFlags)MeComVarConvert.ReadUint8(rxFrame.Payload);
                parMetaData.NrOfInst        = MeComVarConvert.ReadUint8(rxFrame.Payload);
                parMetaData.MaxNrOfElements = MeComVarConvert.ReadUint32(rxFrame.Payload);

                switch (parMetaData.Type)
                {
                case MeParType.FLOAT32:
                    parMetaData.Min   = MeComVarConvert.ReadFloat32(rxFrame.Payload);
                    parMetaData.Max   = MeComVarConvert.ReadFloat32(rxFrame.Payload);
                    parMetaData.Value = MeComVarConvert.ReadFloat32(rxFrame.Payload);
                    break;

                case MeParType.INT32:
                    parMetaData.Min   = MeComVarConvert.ReadInt32(rxFrame.Payload);
                    parMetaData.Max   = MeComVarConvert.ReadInt32(rxFrame.Payload);
                    parMetaData.Value = MeComVarConvert.ReadInt32(rxFrame.Payload);
                    break;

                case MeParType.DOUBLE64:
                    parMetaData.Min   = MeComVarConvert.ReadDouble64(rxFrame.Payload);
                    parMetaData.Max   = MeComVarConvert.ReadDouble64(rxFrame.Payload);
                    parMetaData.Value = MeComVarConvert.ReadDouble64(rxFrame.Payload);
                    break;

                case MeParType.LATIN1:
                case MeParType.BYTE:
                    parMetaData.Min   = MeComVarConvert.ReadUint8(rxFrame.Payload);
                    parMetaData.Max   = MeComVarConvert.ReadUint8(rxFrame.Payload);
                    parMetaData.Value = null;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Unknown Type received. Received value: " + parMetaData.Type);
                }
                return(parMetaData);
            }
            catch (Exception Ex)
            {
                throw new ComCommandException(String.Format("Get Meta Data failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
            }
        }
Пример #5
0
 /// <summary>
 /// Resets the device.
 /// Usually the device does answer to this command, because the reset is slightly delayed.
 /// During reboot, the device can not answer to commands.
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public void ResetDevice(byte?address)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "RS");
         meQuerySet.Set(txFrame);
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Reset Device failed: Address: {0}, Detail: {1}", address, Ex.Message), Ex);
     }
 }
Пример #6
0
 /// <summary>
 /// Downloads a portion of a meerstetter firmware update file (*.mefw) to the device.
 /// This method must be called several times to download the whole content of the file.
 /// This method converts the data base64url and sends it.
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <param name="buffer">Portion of *.mefw file.</param>
 /// <param name="length">Length of the portion to download.</param>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public void DownloadFirmwareData(byte?address, byte[] buffer, int length)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "BS");
         MeComVarConvert.AddBase64url(txFrame.Payload, buffer, length);
         meQuerySet.Set(txFrame);
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("DownloadFirmwareData failed: Address: {0}; Detail: {1}", address, Ex.Message), Ex);
     }
 }
Пример #7
0
 /// <summary>
 /// Queries the Branch ID.
 /// The Branch ID can be used to identify several software branches from the same software.
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <returns>Branch ID</returns>
 public int GetBranchId(byte?address)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "?BI");
         MeComPacket rxFrame = meQuerySet.Query(txFrame);
         return(MeComVarConvert.ReadInt32(rxFrame.Payload));
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Get Branch ID failed: Address: {0}; Detail: {1}", address, Ex.Message), Ex);
     }
 }
Пример #8
0
 /// <summary>
 /// Changes the baud rate of the device on the interface where this command is being received.
 /// Do not forget to change the host baud rate after this command (MeComSetDefaultSettings).
 /// Most devices will fall back to the old baud rate if there is no further command being received after CS within 5s.
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <param name="newBaudRate">New baud rate to be set on the devices interface.</param>
 public void ChangeComSpeed(byte?address, uint newBaudRate)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "CS");
         MeComVarConvert.AddUint32(txFrame.Payload, newBaudRate);
         MeComPacket RxFrame = meQuerySet.Set(txFrame);
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Speed Change failed: Address: {0}, Detail: {1}", address, Ex.Message), Ex);
     }
 }
Пример #9
0
 /// <summary>
 /// Returns the Device Identification String.
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <returns>Device Identification String. Usually 20 Chars long.</returns>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public string GetIdentString(byte?address)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "?IF");
         MeComPacket rxFrame = meQuerySet.Query(txFrame);
         return(MeComVarConvert.ReadString(rxFrame.Payload, 20));
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Get Identification String failed: Address: {0}, Detail: {1}", address, Ex.Message), Ex);
     }
 }
Пример #10
0
 /// <summary>
 /// Returns a double 64Bit value from the device.
 /// </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>
 /// <returns>Returned value.</returns>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public double GetDoubleValue(byte?address, UInt16 parameterId, byte instance)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "?VR");
         MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
         MeComVarConvert.AddUint8(txFrame.Payload, instance);
         MeComPacket rxFrame = meQuerySet.Query(txFrame);
         return(MeComVarConvert.ReadDouble64(rxFrame.Payload));
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Get Double Value failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
     }
 }
Пример #11
0
 /// <summary>
 /// Sets a double 64Bit value to the device.
 /// </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="value">Value to set.</param>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public void SetDoubleValue(byte?address, UInt16 parameterId, byte instance, double value)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "VS");
         MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
         MeComVarConvert.AddUint8(txFrame.Payload, instance);
         MeComVarConvert.AddDouble64(txFrame.Payload, value);
         meQuerySet.Set(txFrame);
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Set Double Value failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
     }
 }
Пример #12
0
 /// <summary>
 /// Sends out a command to set the device address by type and serial number
 /// </summary>
 /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
 /// <param name="deviceType">Type of the device.</param>
 /// <param name="serialNumber">Serial number of the Device</param>
 /// <param name="setaddress">Address to be set.</param>
 /// <param name="option">Option. 0=Set address, 1=rack system.</param>
 /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
 public void SetDeviceAddress(byte?address, int deviceType, int serialNumber, byte setaddress, byte option)
 {
     try
     {
         MeComPacket txFrame = new MeComPacket('#', address);
         MeComVarConvert.AddString(txFrame.Payload, "SA");
         MeComVarConvert.AddInt32(txFrame.Payload, deviceType);
         MeComVarConvert.AddInt32(txFrame.Payload, serialNumber);
         MeComVarConvert.AddUint8(txFrame.Payload, option);
         MeComVarConvert.AddUint8(txFrame.Payload, setaddress);
         meQuerySet.Set(txFrame);
     }
     catch (Exception Ex)
     {
         throw new ComCommandException(String.Format("Set Device Address failed: Address: {0}; Device Type: {1}; Serial Number: {2}; Address to be set: {3}", deviceType, serialNumber, setaddress, Ex.Message), Ex);
     }
 }
Пример #13
0
        /// <summary>
        /// Serializes the given Data structure to a proper
        /// frame and sends it to the physical interface.
        /// It returns immediately.
        /// </summary>
        /// <param name="txFrame">Data to send.</param>
        /// <exception cref="MeComPhyIntefaceException">Thrown when the underlying physical interface is not or not all bytes were sent.</exception>
        public void SendFrame(MeComPacket txFrame)
        {
            MemoryStream TxStream = new MemoryStream();

            TxStream.WriteByte(Convert.ToByte(txFrame.Control));
            MeComVarConvert.AddUint8(TxStream, (byte)txFrame.Address);
            MeComVarConvert.AddUint16(TxStream, txFrame.SeqNr);
            txFrame.Payload.WriteTo(TxStream);
            LastCRC = CalcCRC_CITT(TxStream);
            MeComVarConvert.AddUint16(TxStream, LastCRC);

            TxStream.WriteByte(0x0D);
            statistics.AddTxBytes(TxStream.Length);
            statistics.IncTxFrames();
            PhyCom.SendString(TxStream);
            TxStream.Position = 0;
            TraceLog.Verbose("Thread: '{0}' TX: {1}", Thread.CurrentThread.Name, new StreamReader(TxStream).ReadToEnd().Replace("\r", "<CR>").Replace("\n", "<LF>"));
        }
Пример #14
0
        /// <summary>
        /// Reads a list of values from the device within one command.
        /// This is much more efficient than reading each value with an separate command.
        /// </summary>
        /// <param name="address">Device Address. Use null to use the DefaultDeviceAddress defined on MeComQuerySet.</param>
        /// <param name="elements">List of parameter definitions to read from the device.</param>
        /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
        public void BulkParRead(byte?address, List <BulkParElement> elements)
        {
            try
            {
                MeComPacket txFrame = new MeComPacket('#', address);
                MeComVarConvert.AddString(txFrame.Payload, "?VX");
                MeComVarConvert.AddUint8(txFrame.Payload, (byte)elements.Count);

                foreach (BulkParElement item in elements)
                {
                    MeComVarConvert.AddUint16(txFrame.Payload, item.ParameterId);
                    MeComVarConvert.AddUint8(txFrame.Payload, item.Instance);
                }
                MeComPacket rxFrame = meQuerySet.Query(txFrame);
                foreach (BulkParElement item in elements)
                {
                    switch (item.Type)
                    {
                    case MeParType.FLOAT32:
                        item.Value = MeComVarConvert.ReadFloat32(rxFrame.Payload);
                        break;

                    case MeParType.INT32:
                        item.Value = MeComVarConvert.ReadInt32(rxFrame.Payload);
                        break;

                    case MeParType.DOUBLE64:
                        item.Value = MeComVarConvert.ReadDouble64(rxFrame.Payload);
                        break;
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new ComCommandException(String.Format("Bulk Parameter read failed Detail: {0}", Ex.Message), Ex);
            }
        }
Пример #15
0
        MeComPacket LocalSet(MeComPacket txFrame)
        {
            if (txFrame.Address == null)
            {
                txFrame.Address = DefaultDeviceAddress;
            }

            sequenceNr++;
            int         trialsLeft = 3;
            MeComPacket rxFrame    = new MeComPacket();

            while (trialsLeft > 0)
            {
                trialsLeft--;
                txFrame.SeqNr = sequenceNr;

                try
                {
                    meFrame.SendFrame(txFrame);
                    if (txFrame.Address == 255)
                    {
                        return(rxFrame);                        //On the address 255, no answer is expected
                    }
                    rxFrame = meFrame.ReceiveFrameOrTimeout();

                    if (rxFrame.SeqNr == sequenceNr && rxFrame.Address == txFrame.Address)
                    {
                        //Corresponding Frame received
                        if (rxFrame.RcvType == ERcvType.Data)
                        {
                            //Data Frame received --> Check for error code
                            if (rxFrame.Payload.ReadByte() == '+')
                            {
                                SetServerErrorException(MeComVarConvert.ReadUint8(rxFrame.Payload));
                            }
                            else
                            {
                                rxFrame.Payload.Position = 0; //Set stream position to 0 for the user
                                return(rxFrame);
                            }
                        }
                        else if (rxFrame.RcvType == ERcvType.ACK)
                        {
                            return(rxFrame);
                        }
                    }
                }
                catch (MeComPhyTimeoutException Ex)
                {
                    //Ignore Timeout on this level if some trials are left
                    if (trialsLeft == 0)
                    {
                        throw new GeneralException("Set failed: Timeout!", Ex);
                    }
                    TraceLog.Info("Thread '{0}': Package re-send. NrOfTrails {1}", Thread.CurrentThread.Name, trialsLeft);
                }
                catch (ServerException)
                {
                    throw;
                }
                catch (Exception Ex)
                {
                    throw new GeneralException("Set failed: " + Ex.Message, Ex);
                }
            }

            //Communication failed, check last error
            if (rxFrame.SeqNr != sequenceNr)
            {
                throw new GeneralException("Set failed: Wrong Sequence Number received. Received " + rxFrame.SeqNr + "; Expected " + sequenceNr);
            }
            if (rxFrame.Address != txFrame.Address)
            {
                throw new GeneralException("Set failed: Wrong Address received. Received " + rxFrame.Address + "; Expected " + txFrame.Address);
            }

            throw new GeneralException("Set failed: Unknown error");
        }
Пример #16
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
            }
        }
Пример #17
0
        /// <summary>
        /// Writes an array of FLOAT32, INT32, DOUBLE64 or ASCII (char) values to the device.
        /// The data length is given by the value parameter.
        /// This method does only return when all data is downloaded.
        /// The data is being written 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 written.</param>
        /// <param name="values">Data to be written (can be float[], int[], double[] or string.</param>
        /// <param name="callback">Is called every time when the progress has changed.</param>
        /// <exception cref="ComCommandException">when the command fails. Check the inner exception for details.</exception>
        public void SetBigData(byte?address, UInt16 parameterId, byte instance, MeParType type, dynamic values, ProgressUpdateCallback callback)
        {
            int maxDataSize            = meQuerySet.MaxTxPayloadSize - 22; //-xx Bytes used for commands
            int nrOfElementsPerPackage = 0;

            switch (type)
            {
            case MeParType.FLOAT32:
                nrOfElementsPerPackage = maxDataSize / 8;
                break;

            case MeParType.INT32:
                nrOfElementsPerPackage = maxDataSize / 8;
                break;

            case MeParType.DOUBLE64:
                nrOfElementsPerPackage = maxDataSize / 16;
                break;

            case MeParType.LATIN1:
                values += (char)0;     //Add zero terminator
                nrOfElementsPerPackage = maxDataSize / 2;
                break;

            case MeParType.BYTE:
                nrOfElementsPerPackage = maxDataSize / 2;
                break;

            default:
                throw new ArgumentOutOfRangeException("Unknown EParType: " + type);
            }
            int nrOfPackages = (values.Length - 1) / nrOfElementsPerPackage + 1;

            try
            {
                int          totalSentElements = 0;
                MemoryStream totalStream       = new MemoryStream();

                for (int packageNr = 0; packageNr < nrOfPackages; packageNr++)
                {
                    bool lastPackage = (packageNr + 1) == nrOfPackages;
                    int  nrOfElementsInThisPackage = values.Length - totalSentElements;
                    if (nrOfElementsInThisPackage > nrOfElementsPerPackage)
                    {
                        nrOfElementsInThisPackage = nrOfElementsPerPackage;
                    }

                    MeComPacket txFrame = new MeComPacket('#', address);
                    MeComVarConvert.AddString(txFrame.Payload, "VB");
                    MeComVarConvert.AddUint16(txFrame.Payload, parameterId);
                    MeComVarConvert.AddUint8(txFrame.Payload, instance);
                    MeComVarConvert.AddUint32(txFrame.Payload, (uint)totalSentElements); //write start position
                    MeComVarConvert.AddUint16(txFrame.Payload, (ushort)nrOfElementsInThisPackage);
                    if (lastPackage)
                    {
                        MeComVarConvert.AddUint8(txFrame.Payload, 1);
                    }
                    else
                    {
                        MeComVarConvert.AddUint8(txFrame.Payload, 0);
                    }

                    switch (type)
                    {
                    case MeParType.FLOAT32:
                        for (int i = 0; i < nrOfElementsInThisPackage; i++)
                        {
                            MeComVarConvert.AddFloat32(txFrame.Payload, values[totalSentElements + i]);
                        }
                        break;

                    case MeParType.INT32:
                        for (int i = 0; i < nrOfElementsInThisPackage; i++)
                        {
                            MeComVarConvert.AddUint32(txFrame.Payload, values[totalSentElements + i]);
                        }
                        break;

                    case MeParType.DOUBLE64:
                        for (int i = 0; i < nrOfElementsInThisPackage; i++)
                        {
                            MeComVarConvert.AddDouble64(txFrame.Payload, values[totalSentElements + i]);
                        }
                        break;

                    case MeParType.LATIN1:
                        MeComVarConvert.AddEncodedString(txFrame.Payload, values.Substring(totalSentElements, nrOfElementsInThisPackage));
                        break;

                    case MeParType.BYTE:
                        for (int i = 0; i < nrOfElementsInThisPackage; i++)
                        {
                            MeComVarConvert.AddUint8(txFrame.Payload, values[totalSentElements + i]);
                        }
                        break;
                    }
                    int timeout = 0;
                    while (timeout < 50) //Manage device busy
                    {
                        timeout++;
                        try
                        {
                            meQuerySet.Set(txFrame);
                            break;
                        }
                        catch (ServerException ex)
                        {
                            if (ex.ServerErrorCode != 2)
                            {
                                throw;
                            }
                            TraceLog.Verbose("Device busy detected. Timeout {0}", timeout);
                            Thread.Sleep(10);
                        }
                    }

                    totalSentElements += nrOfElementsInThisPackage;
                    callback?.Invoke(100.0 / nrOfPackages * (packageNr + 1));
                }
            }
            catch (Exception Ex)
            {
                throw new ComCommandException(String.Format("Set Value failed: Address: {0}; ID: {1}; Inst: {2}; Detail: {3}", address, parameterId, instance, Ex.Message), Ex);
            }
        }
Пример #18
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);
            }
        }