More iPerlCommunication changes: read/write Q2 correction factors from/to memory, cleanup of all functions.

This commit is contained in:
Milan Hanajik 2015-08-15 17:51:54 +02:00
parent 68a038d321
commit ee044e3dd7

View File

@ -379,6 +379,10 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
#endregion
/// <summary>
/// Worker thread
/// </summary>
/// <param name="threadData">Thread ID (integer) wrapped into IntBox</param>
static void Worker(object threadData)
{
int threadId = (threadData as Boxes.IntBox).Val;
@ -402,15 +406,30 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
wmFound = true;
if (wm.DebugLevel == Entities.DebugMode.Normal)
{
if (activity.ToLower().Contains(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"));
}
bool success;
string resultStr = string.Empty;
if (activity.ToLower().Contains(ReadConfigurationStr.ToLower())) success = ReadConfiguration(wm, ref resultStr);
else if (activity.ToLower().Contains(SetTestModeStr.ToLower())) success = SetTestMode(wm, ref resultStr);
else if (activity.ToLower().Equals(SetActiveModeStr.ToLower())) success = SetActiveMode(wm, ref resultStr);
else if (activity.ToLower().Equals(ReadCalibrationStr.ToLower())) success = ReadCalibration(wm, ref resultStr);
else if (activity.ToLower().Equals(WriteCalibrationFactorStr.ToLower())) success = WriteCalibrationFactor(wm, ref resultStr);
else if (activity.ToLower().Equals(ResetQ2CorrectionStr.ToLower())) success = ResetQ2Correction(wm, ref resultStr);
else if (activity.ToLower().Equals(WriteQ2CorrectionStr.ToLower())) success = WriteQ2Correction(wm, ref resultStr);
else
{
success = true;
resultStr = "Invalid activity";
}
if (success) OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, resultStr));
else if (wm.Disabled) OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
else
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot " + activity));
wm.Disabled = true;
}
}
else
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Simulation"));
@ -425,58 +444,49 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
}
}
/// <summary>
/// Read a complete configuration structure of the watermeter
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void ReadConfiguration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool ReadConfiguration(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
bool success = false;
byte[] config = null;
///
/// The activity is "Read configuration" (this enables the watermeter, resets error flag)
/// or "Read configuration if enabled" (this keeps th error flag).
///
if (!activity.ToLower().Contains(" if enabled")) { wm.Disabled = false; }
if (!activity.ToLower().Contains(" if enabled"))
{
wm.Disabled = false;
}
if (wm.Disabled) return false;
if (!wm.Disabled)
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = false;
/// Read configuration
byte[] config = null;
for (int j = 0; j < MaxCommRetries; j++)
{
success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port
if (success)
{
success = false;
/// Read configuration
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out config, CommTimeout)) { success = true; break; }
}
}
closePort(); /// Close RFID port
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out config, CommTimeout))
{
success = true;
wm.ConfigStruct = ConfigStruct.FromByteArray(config);
resultStr = wm.ConfigStruct.ToString(1);
break;
}
}
if (success)
{
wm.ConfigStruct = ConfigStruct.FromByteArray(config);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1)));
}
else if (wm.Disabled)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
wm.Disabled = true;
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read configuration"));
}
closePort(); /// Close RFID port
return success;
}
/// <summary>
/// Set the watermeter to the test mode.
/// If testModeConfig is specified as a hexadeximal number appended to "set test mode ", it is verified
@ -484,290 +494,323 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// Read a part of configuration afterwards to verify the mode was set correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void SetTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool SetTestMode(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
bool success = false;
if (!wm.Disabled)
if (wm.Disabled) return false;
Byte testModeConfig = 0xA0; /// Default value
///
if (activity.Length > SetTestModeStr.Length)
{
Byte testModeConfig = 0xA0; /// Default value
///
if (activity.Length > SetTestModeStr.Length)
string testModeConfigStr = activity.Substring(SetTestModeStr.Length + 1);
UInt16 byteVal;
if (UInt16.TryParse(testModeConfigStr, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byteVal) && byteVal <= 255)
{
string testModeConfigStr = activity.Substring(SetTestModeStr.Length + 1);
UInt16 byteVal;
if (UInt16.TryParse(testModeConfigStr, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byteVal) && byteVal <= 255)
{
testModeConfig = (Byte)byteVal; /// Update with specified value
}
testModeConfig = (Byte)byteVal; /// Update with specified value
}
}
if (wm.ConfigStruct.MeterState == MeterState.Test && wm.ConfigStruct.TestModeConfig == testModeConfig)
if (wm.ConfigStruct.MeterState == MeterState.Test && wm.ConfigStruct.TestModeConfig == testModeConfig)
{
/// Already in the correct test mode
return true;
}
/// Communication necessary
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = true;
if (success && (wm.ConfigStruct.TestModeConfig != testModeConfig) && (wm.ConfigStruct.MeterState != MeterState.Active))
{
/// Switch to Active mode in order to change TestModeConfig
success = false;
byte[] cmd = new byte[1] { (byte)6 };
for (int j = 0; j < MaxCommRetries; j++)
{
/// Already in the correct test mode
success = true;
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
else
}
if (success && (wm.ConfigStruct.TestModeConfig != testModeConfig))
{
/// Change the TestModeConfig if necessary
success = false;
byte[] tstMdCfg = new byte[1] { testModeConfig };
for (int j = 0; j < MaxCommRetries; j++)
{
/// Communication necessary
success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
if (success && (wm.ConfigStruct.TestModeConfig != testModeConfig) && (wm.ConfigStruct.MeterState != MeterState.Active))
if (0 == WriteRequestPort(MessageID.Configuration, 21, 1, tstMdCfg, CommTimeout))
{
/// Switch to Active mode in order to change TestModeConfig
success = false;
byte[] cmd = new byte[1] { (byte)6 };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
wm.ConfigStruct.Update(21, tstMdCfg);
success = true;
break;
}
if (success && (wm.ConfigStruct.TestModeConfig != testModeConfig))
{
/// Change the TestModeConfig if necessary
success = false;
byte[] tstMdCfg = new byte[1] { testModeConfig };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Configuration, 21, 1, tstMdCfg, CommTimeout))
{
wm.ConfigStruct.Update(21, tstMdCfg);
success = true;
break;
}
}
}
if (success)
{
/// Switch to test mode
success = false;
byte[] cmd = new byte[1] { (byte)7 };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
}
/// Now the meter should be in the Test mode ... verify
if (success)
{
/// Verify the configuration
success = false;
byte[] cfg_0_3 = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout))
{
wm.ConfigStruct.Update(0, cfg_0_3);
success = (wm.ConfigStruct.MeterState == MeterState.Test);
break;
}
}
}
closePort(); /// Close RFID port
}
}
if (success)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1)));
/// Switch to test mode
success = false;
byte[] cmd = new byte[1] { (byte)7 };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
}
else if (wm.Disabled)
/// Now the meter should be in the Test mode ... verify
if (success)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
wm.Disabled = true;
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "'Set test mode' failed"));
/// Verify the configuration
success = false;
byte[] cfg_0_3 = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout))
{
wm.ConfigStruct.Update(0, cfg_0_3);
success = (wm.ConfigStruct.MeterState == MeterState.Test);
if (success) resultStr = wm.ConfigStruct.ToString(1);
break;
}
}
}
closePort(); /// Close RFID port
return success;
}
/// <summary>
/// Set the watermeter to the active mode.
/// Read a part of configuration afterwards to verify the mode was set correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void SetActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool SetActiveMode(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
if (wm.Disabled) return false;
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = false;
if (!wm.Disabled)
/// Switch to active mode
byte[] cmd = new byte[1] { (byte)6 };
for (int j = 0; j < MaxCommRetries; j++)
{
success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
if (success)
{
success = false;
/// Switch to active mode
byte[] cmd = new byte[1] { (byte)6 };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
}
if (success)
{
success = false;
/// Read configuration
byte[] cfg_0_3 = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout))
{
wm.ConfigStruct.Update(0, cfg_0_3);
success = true;
break;
}
}
}
closePort(); /// Close RFID port
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
}
if (success)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1)));
}
else if (wm.Disabled)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
wm.Disabled = true;
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to active mode"));
success = false;
/// Read configuration
byte[] cfg_0_3 = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout))
{
wm.ConfigStruct.Update(0, cfg_0_3);
success = (wm.ConfigStruct.MeterState == MeterState.Active);
if (success) resultStr = wm.ConfigStruct.ToString(1);
break;
}
}
}
closePort(); /// Close RFID port
return success;
}
/// <summary>
/// Read a complete calibration structure from the watermeter
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void ReadCalibration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool ReadCalibration(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
bool success = false;
byte[] calib = null;
if (wm.Disabled) return false;
//if (activity.Length >
//string testModeConfigStr = activity.Substring(activity.IndexOf()
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
if (!wm.Disabled)
bool success = false;
/// Read calibration
byte[] calib = null;
for (int j = 0; j < MaxCommRetries; j++)
{
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.Calibration, 0, CalibrationStruct.Length, out calib, CommTimeout)) { success = true; break; }
}
}
closePort(); /// Close RFID port
if (0 == ReadRequestPort(MessageID.Calibration, 0, CalibrationStruct.Length, out calib, CommTimeout))
{
success = true;
wm.CalibrationStruct = CalibrationStruct.FromByteArray(calib);
resultStr = wm.CalibrationStruct.ToString();
break;
}
}
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
{
wm.Disabled = true;
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read calibration"));
}
closePort(); /// Close RFID port
return success;
}
/// <summary>
/// Write the calculated calibration factor to the water meter.
/// Read a part of CalibrationStruct afterwards to verify factor was written correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void WriteCalibrationFactor(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool WriteCalibrationFactor(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
if (wm.Disabled) return false;
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = false;
byte[] calib_2_3 = null;
if (!wm.Disabled)
UInt16 factor = wm.CalibrationFactor; /// Original calibration factor
/// Write the calculated calibration factor
UInt16 newCalFactor = wm.CalculatedCalibrationFactor;
byte[] data = new byte[2] { (byte)(newCalFactor & 0x00FF), (byte)((newCalFactor >> 8) & 0x00FF) };
for (int j = 0; j < MaxCommRetries; j++)
{
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 (0 == WriteRequestPort(MessageID.Calibration, 2, 2, data, CommTimeout)) { success = true; break; }
}
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
{
wm.Disabled = true;
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to active mode"));
}
}
success = false;
static void ResetQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "ResetQ2Correction simulated"));
}
/// Read calibration
byte[] calib_2_3 = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Calibration, 2, 2, out calib_2_3, CommTimeout))
{
success = true;
wm.CalibrationStruct.Update(calib_2_3, 2);
resultStr = wm.CalibrationStruct.ToString();
break;
}
}
}
static void WriteQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
closePort(); /// Close RFID port
return success;
}
const int Q2CorrFactorsAddr = 0x1878; /// Used by ResetQ2Correction(...) and WriteQ2Correction(...)
/// <summary>
/// Reset both Q2 correction factors in the memory to 0.
/// Read them back to verify factors were written correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool ResetQ2Correction(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "WriteQ2Correction simulated"));
}
if (wm.Disabled) return false;
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = false;
/// Write zero Q2 correction
Byte q2CorrRFlow = 0;
Byte q2CorrLFlow = 0;
byte[] wrData = new byte[2] { q2CorrRFlow, q2CorrLFlow };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, wrData, CommTimeout)) { success = true; break; }
}
if (success)
{
success = false;
/// Read calibration
byte[] rdData = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if ((0 == ReadRequestPort(MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, out rdData, CommTimeout)) &&
(rdData != null) && (rdData.Length == 2) && (rdData[0] == 0) && (rdData[1] == 0))
{
success = true;
resultStr = "Q2 correction factors reset to 0";
break;
}
}
}
closePort(); /// Close RFID port
return success;
}
/// <summary>
/// Write the calculated Q2 correction factors to the memory.
/// Read them back to verify factors were written correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static bool WriteQ2Correction(WaterMeters.iPerl.WaterMeter wm, ref string resultStr)
{
if (wm.Disabled) return false;
if (openPort(wm.RfidComPortNr) != 0) return false; /// Open RFID port
bool success = false;
/// Write Q2 corrections
Byte q2CorrRFlow = 0;
Byte q2CorrLFlow = 0;
byte[] wrData = new byte[2] { q2CorrRFlow, q2CorrLFlow };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, wrData, CommTimeout)) { success = true; break; }
}
if (success)
{
success = false;
/// Read calibration
byte[] rdData = null;
for (int j = 0; j < MaxCommRetries; j++)
{
if ((0 == ReadRequestPort(MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, out rdData, CommTimeout)) &&
(rdData != null) && (rdData.Length == 2) && (rdData[0] == q2CorrRFlow) && (rdData[1] == q2CorrRFlow))
{
success = true;
resultStr = string.Format("Q2 correction factors set: RightFlow = {0}, LeftFlow = {1}",
q2CorrRFlow, q2CorrRFlow);
break;
}
}
}
return success;
}
/// <summary>