/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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>")); }
/// <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); } }
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"); }
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 } }
/// <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); } }
/// <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); } }