diff --git a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs index 57658f8a9..26dc101e0 100644 --- a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs +++ b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs @@ -75,6 +75,14 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication const int CommTimeout = 500; const int MaxCommRetries = 3; + const string ReadConfigurationStr = "Read configuration"; + const string SetTestModeStr = "Set Test mode"; /// Example: "Set Test mode 0xA0" + const string SetActiveModeStr = "Set Active mode"; + const string ReadCalibrationStr = "Read calibration"; + const string WriteCalibrationFactorStr = "Write calibration factor"; + const string ResetQ2CorrectionStr = "Reset Q2 correction"; + const string WriteQ2CorrectionStr = "Write Q2 correction"; + // Set to 'true' when the form closes public bool Completed { get { return formCompleted; } } @@ -393,10 +401,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication wmFound = true; if (wm.DebugLevel == Entities.DebugMode.Normal) { - if (activity.ToLower().Equals("read configuration")) ReadConfig(wm, threadId, wmNr); - else if (activity.ToLower().Equals("read calibration")) ReadCalibration(wm, threadId, wmNr); - else if (activity.ToLower().Contains("set test mode")) SetToTestMode(wm, threadId, wmNr); - else if (activity.ToLower().Equals("set active mode")) SetToActiveMode(wm, threadId, wmNr); + if (activity.ToLower().Equals(ReadConfigurationStr.ToLower())) ReadConfiguration(wm, threadId, wmNr); + else if (activity.ToLower().Contains(SetTestModeStr.ToLower())) SetTestMode(wm, threadId, wmNr); + else if (activity.ToLower().Equals(SetActiveModeStr.ToLower())) SetActiveMode(wm, threadId, wmNr); + else if (activity.ToLower().Equals(ReadCalibrationStr.ToLower())) ReadCalibration(wm, threadId, wmNr); + else if (activity.ToLower().Equals(WriteCalibrationFactorStr.ToLower())) WriteCalibrationFactor(wm, threadId, wmNr); + else if (activity.ToLower().Equals(ResetQ2CorrectionStr.ToLower())) ResetQ2Correction(wm, threadId, wmNr); + else if (activity.ToLower().Equals(WriteQ2CorrectionStr.ToLower())) WriteQ2Correction(wm, threadId, wmNr); else OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Invalid activity")); } else @@ -419,7 +430,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication /// Water meter object /// Thread ID /// Water meter number 1 .. 40 - static void ReadConfig(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + static void ReadConfiguration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) { bool success = false; byte[] config = null; @@ -445,7 +456,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication if (success) { wm.ConfigStruct = ConfigStruct.FromByteArray(config); - OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(config).ToString(1))); + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1))); } else if (wm.Disabled) { @@ -457,50 +468,6 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication } } - /// - /// Read a complete calibration structure of the watermeter - /// - /// Water meter object - /// Thread ID - /// Water meter number 1 .. 40 - static void ReadCalibration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) - { - bool success = false; - byte[] calib = null; - - if (!wm.Disabled) - { - success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port - - if (success) - { - success = false; - - /// Read calibration - for (int j = 0; j < MaxCommRetries; j++) - { - if (0 == ReadRequestPort(MessageID.Configuration, 0, CalibrationStruct.Length, out calib, CommTimeout)) { success = true; break; } - } - } - - closePort(); /// Close RFID port - } - - if (success) - { - wm.CalibrationStruct = CalibrationStruct.FromByteArray(calib); - OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Calibration successfully read")); - } - else if (wm.Disabled) - { - OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled")); - } - else - { - OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read calibration")); - } - } - /// /// Set the watermeter to the test mode. /// If testModeConfig is specified as a hexadeximal number appended to "set test mode ", it is verified @@ -510,13 +477,16 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication /// Water meter object /// Thread ID /// Water meter number 1 .. 40 - static void SetToTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + static void SetTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) { bool success = false; byte[] cfg_0_3 = null; if (!wm.Disabled) { + string testModeConfigStr; /// TODO + Byte testModeConfig; /// TODO + success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port if (success) @@ -560,8 +530,14 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication } } - - static void SetToActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + /// + /// Set the watermeter to the active mode. + /// Read a part of configuration afterwards to verify the mode was set correctly. + /// + /// Water meter object + /// Thread ID + /// Water meter number 1 .. 40 + static void SetActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) { bool success = false; byte[] cfg_0_3 = null; @@ -589,7 +565,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication /// Read configuration for (int j = 0; j < MaxCommRetries; j++) { - if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out cfg_0_3, CommTimeout)) { success = true; break; } + if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout)) { success = true; break; } } } @@ -598,7 +574,8 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication if (success) { - OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(cfg_0_3).ToString(1))); + wm.ConfigStruct.Update(cfg_0_3, 0); + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1))); } else if (wm.Disabled) { @@ -610,6 +587,123 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication } } + /// + /// Read a complete calibration structure from the watermeter + /// + /// Water meter object + /// Thread ID + /// Water meter number 1 .. 40 + static void ReadCalibration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + { + bool success = false; + byte[] calib = null; + + //if (activity.Length > + //string testModeConfigStr = activity.Substring(activity.IndexOf() + + if (!wm.Disabled) + { + success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port + + if (success) + { + success = false; + + /// Read calibration + for (int j = 0; j < MaxCommRetries; j++) + { + if (0 == ReadRequestPort(MessageID.Configuration, 0, CalibrationStruct.Length, out calib, CommTimeout)) { success = true; break; } + } + } + + closePort(); /// Close RFID port + } + + if (success) + { + wm.CalibrationStruct = CalibrationStruct.FromByteArray(calib); + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.CalibrationStruct.ToString())); + } + else if (wm.Disabled) + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled")); + } + else + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read calibration")); + } + } + + /// + /// Write the calculated calibration factor to the water meter. + /// Read a part of CalibrationStruct afterwards to verify factor was written correctly. + /// + /// Water meter object + /// Thread ID + /// Water meter number 1 .. 40 + static void WriteCalibrationFactor(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + { + bool success = false; + byte[] calib_2_3 = null; + + if (!wm.Disabled) + { + success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port + + if (success) + { + success = false; + + ushort factor = wm.CalibrationFactor; + + /// Switch to active mode + UInt16 newCalFactor = wm.CalculatedCalibrationFactor; + byte[] data = new byte[2] { (byte)(newCalFactor & 0x00FF), (byte)((newCalFactor >> 8) & 0x00FF) }; + for (int j = 0; j < MaxCommRetries; j++) + { + if (0 == WriteRequestPort(MessageID.Calibration, 2, 2, data, CommTimeout)) { success = true; break; } + } + } + + if (success) + { + success = false; + + /// Read configuration + for (int j = 0; j < MaxCommRetries; j++) + { + if (0 == ReadRequestPort(MessageID.Calibration, 2, 2, out calib_2_3, CommTimeout)) { success = true; break; } + } + } + + closePort(); /// Close RFID port + } + + if (success) + { + wm.CalibrationStruct.Update(calib_2_3, 2); + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.CalibrationStruct.ToString())); + } + else if (wm.Disabled) + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled")); + } + else + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to active mode")); + } + } + + static void ResetQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "ResetQ2Correction simulated")); + } + + static void WriteQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr) + { + OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "WriteQ2Correction simulated")); + } + /// /// Called when communication with one watermeter is completed diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/CalibrationStruct.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/CalibrationStruct.cs index a69c19d56..19794e570 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/CalibrationStruct.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/CalibrationStruct.cs @@ -89,7 +89,12 @@ namespace TBF.BenchControl.WaterMeters.iPerl return result; } - public static CalibrationStruct FromByteArray(byte[] data) + /// + /// Create a calibration structure from a complete byte array + /// + /// A complete byte array data + /// CalibrationStruct or null when byte array was not complete + public static CalibrationStruct FromByteArray(byte[] data) { if (data.Length != Length) return null; @@ -117,6 +122,46 @@ namespace TBF.BenchControl.WaterMeters.iPerl return result; } + /// + /// Update the calibration structure from an incomplete byte array + /// + /// Byte array data + /// Offset of byte array data in CalibrationStruct + /// true when successful, false when data are not appropriate + public bool Update(byte[] data, int offset) + { + if (offset == 2 && data.Length == 2) + { + /// Data containing iPerl calibration factor + Calibration = (UInt16)(data[2 - offset] + 256 * data[3 - offset]); + return true; + } + else if (offset == 0 && data.Length == Length) + { + /// Data containing a complete CalibrationStruct + Version = data[0]; + MeterType = (MeterType)data[1]; + Calibration = (UInt16)(data[2] + 256 * data[3]); + VolumeUnits = (VolumeUnits)data[4]; + FlowArrow = (FlowArrow)data[5]; + FWVersion = (UInt16)(data[6] + 256 * data[7]); + TargetField[0] = (UInt16)(data[8] + 256 * data[9]); + TargetField[1] = (UInt16)(data[10] + 256 * data[11]); + TargetField[2] = (UInt16)(data[12] + 256 * data[13]); + RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]); + ThresholdVolume = (UInt16)(data[16] + 256 * data[17]); + ThresholdTime = (UInt16)(data[18] + 256 * data[19]); + FlowActivationThr = (UInt16)(data[20] + 256 * data[21]); + VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]); + CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24]; + SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28]; + MeterSealed = (MeterSealed)data[33]; + CheckSum = data[34]; + return true; + } + else + return false; + } public override string ToString() { diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs index 09606c281..5cb4138c9 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs @@ -78,6 +78,16 @@ namespace TBF.BenchControl.WaterMeters.iPerl /// public CalibrationStruct CalibrationStruct; + public ushort CalibrationFactor { get { return CalibrationStruct.Calibration; } } + + public ushort CalculatedCalibrationFactor + { + get + { + return (UInt16)((double)CalibrationStruct.Calibration * 1.1); /// TODO: real calculation + } + } + Boxes.IntBox pulses; Boxes.IntBox refPulses;