2015-08-11 06:50:32 +00:00
///
2017-03-19 21:03:31 +00:00
/// Copyright (c) 2015-2017 Sensus Metering Systems
2015-08-11 06:50:32 +00:00
///
2016-10-27 12:27:37 +00:00
//#define VERIFY_ACTIVE_MODE
//#define VERIFY_Q2_CORR_RESET
2015-08-11 06:50:32 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing ;
2015-08-14 17:20:47 +00:00
using System.Globalization ;
2015-08-11 06:50:32 +00:00
using System.Runtime.InteropServices ;
2016-04-19 08:10:51 +00:00
using System.Text ;
2015-08-11 06:50:32 +00:00
using System.Threading ;
using System.Windows.Forms ;
using log4net ;
2015-12-04 16:17:20 +00:00
using Config.Entities ;
2015-08-11 06:50:32 +00:00
using TBF.Resources ;
2016-01-03 01:05:35 +00:00
using TBF.BenchControl.Sequences ;
2017-05-31 12:51:26 +00:00
using TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead ;
2015-08-11 06:50:32 +00:00
namespace TBF.BenchControl.TestMethods.iPerlCommunication
{
2015-08-17 14:02:30 +00:00
public enum CommErr
{
None = 0 ,
2015-09-11 12:15:32 +00:00
CommFailed ,
2015-08-17 14:02:30 +00:00
OpenPort ,
Read ,
Write ,
2016-11-10 13:07:11 +00:00
ReadAfterWrite ,
2015-08-17 14:02:30 +00:00
CmdActive ,
CmdTest ,
Verify ,
2017-04-28 08:14:49 +00:00
WrongIPerlType ,
2017-06-07 14:22:18 +00:00
CalibFactorOoRange ,
2017-07-14 14:31:35 +00:00
MissingTest ,
2015-08-17 14:02:30 +00:00
}
2015-08-11 06:50:32 +00:00
public partial class iPerlCommunicationForm : Form , GenericDevices . IHasCompleted
{
2015-08-19 11:04:47 +00:00
private static readonly ILog log = LogManager . GetLogger ( typeof ( iPerlCommunicationForm ) ) ;
2015-08-15 21:01:26 +00:00
protected static readonly ILog rfidDataLogger = LogManager . GetLogger ( "RfidData" ) ;
2015-08-11 06:50:32 +00:00
#region DLL_Interface
2015-08-19 11:04:47 +00:00
[DllImport("libRfid1.dll", EntryPoint = "getDllVersion")] static extern unsafe int getDllVersion1 ( ) ;
[DllImport("libRfid1.dll", EntryPoint = "openPort")] static extern unsafe int openPort1 ( int comPort ) ;
[DllImport("libRfid1.dll", EntryPoint = "closePort")] static extern unsafe int closePort1 ( ) ;
[DllImport("libRfid1.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort1 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
[DllImport("libRfid1.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort1 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
2015-08-11 06:50:32 +00:00
2015-08-19 11:04:47 +00:00
[DllImport("libRfid2.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion2 ( ) ;
[DllImport("libRfid2.dll", EntryPoint = "openPort")] static extern unsafe int openPort2 ( int comPort ) ;
[DllImport("libRfid2.dll", EntryPoint = "closePort")] static extern unsafe int closePort2 ( ) ;
[DllImport("libRfid2.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort2 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
[DllImport("libRfid2.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort2 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
2015-08-11 06:50:32 +00:00
2015-08-19 11:04:47 +00:00
[DllImport("libRfid3.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion3 ( ) ;
[DllImport("libRfid3.dll", EntryPoint = "openPort")] static extern unsafe int openPort3 ( int comPort ) ;
[DllImport("libRfid3.dll", EntryPoint = "closePort")] static extern unsafe int closePort3 ( ) ;
[DllImport("libRfid3.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort3 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
[DllImport("libRfid3.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort3 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
2015-08-11 06:50:32 +00:00
2015-08-19 11:04:47 +00:00
[DllImport("libRfid4.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion4 ( ) ;
[DllImport("libRfid4.dll", EntryPoint = "openPort")] static extern unsafe int openPort4 ( int comPort ) ;
[DllImport("libRfid4.dll", EntryPoint = "closePort")] static extern unsafe int closePort4 ( ) ;
[DllImport("libRfid4.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort4 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
[DllImport("libRfid4.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort4 ( MessageID messageId , int offset , int lenght , byte * ptr , int timeout_ms ) ;
2015-08-11 06:50:32 +00:00
2015-08-19 11:04:47 +00:00
/// <summary>
/// Wrapper function with safe interface and unsafe body
/// </summary>
/// <param name="boardNr">0..3</param>
/// <param name="comPort">Com port number</param>
/// <returns>Value returned by openPort(...)</returns>
2017-05-31 12:51:26 +00:00
public static unsafe int OpenPort ( IperlHead iperlHead )
2015-08-19 11:04:47 +00:00
{
2017-05-31 12:51:26 +00:00
if ( iperlHead . DebugLevel ! = DebugMode . Normal ) return 0 ; /// No function in debug mode
2015-08-27 05:03:42 +00:00
2017-05-31 12:51:26 +00:00
if ( iperlHead . RfidComPortNr > 0 )
2015-08-19 11:04:47 +00:00
{
2017-05-31 12:51:26 +00:00
return openPort1 ( iperlHead . RfidComPortNr ) ;
2016-04-18 11:38:13 +00:00
}
else
{
2017-05-31 12:51:26 +00:00
switch ( iperlHead . MuxBoardNr )
2016-04-18 11:38:13 +00:00
{
default :
case 1 : return openPort1 ( cfg . RfidPortNrBoard1 ) ;
case 2 : return openPort2 ( cfg . RfidPortNrBoard2 ) ;
case 3 : return openPort3 ( cfg . RfidPortNrBoard3 ) ;
case 4 : return openPort4 ( cfg . RfidPortNrBoard4 ) ;
}
2015-08-19 11:04:47 +00:00
}
}
2015-08-15 21:01:26 +00:00
/// <summary>
/// Wrapper function with safe interface and unsafe body
/// </summary>
2015-08-19 11:04:47 +00:00
/// <param name="boardNr">0..3</param>
/// <param name="comPort">Com port number</param>
2015-08-15 21:01:26 +00:00
/// <returns>Value returned by openPort(...)</returns>
2017-05-31 12:51:26 +00:00
public static unsafe int ClosePort ( IperlHead iperlHead )
2015-08-15 21:01:26 +00:00
{
2017-05-31 12:51:26 +00:00
if ( iperlHead . DebugLevel ! = DebugMode . Normal ) return 0 ; /// No function in debug mode
2015-08-27 05:03:42 +00:00
2017-05-31 12:51:26 +00:00
if ( iperlHead . RfidComPortNr > 0 )
2016-04-18 11:38:13 +00:00
{
return closePort1 ( ) ;
}
else
2015-08-19 11:04:47 +00:00
{
2017-05-31 12:51:26 +00:00
switch ( iperlHead . MuxBoardNr )
2016-04-18 11:38:13 +00:00
{
default :
case 1 : return closePort1 ( ) ;
case 2 : return closePort2 ( ) ;
case 3 : return closePort3 ( ) ;
case 4 : return closePort4 ( ) ;
}
2015-08-19 11:04:47 +00:00
}
2015-08-15 21:01:26 +00:00
}
2015-08-19 11:04:47 +00:00
/// <summary>
2015-08-15 21:01:26 +00:00
/// Wrapper function with safe interface and unsafe body
2015-08-11 06:50:32 +00:00
/// </summary>
/// <returns>Value returned by readRequestPort(...)</returns>
2017-05-31 12:51:26 +00:00
public static unsafe int ReadRequestPort ( IperlHead iperlHead , MessageID messageID , int offset , int lenght , out byte [ ] buffer , int timeout )
2015-08-11 06:50:32 +00:00
{
2016-10-27 12:27:37 +00:00
buffer = new byte [ lenght ] ;
2017-05-31 12:51:26 +00:00
if ( iperlHead . DebugLevel ! = DebugMode . Normal ) return iperlHead . Name . Equals ( "iPerl13" ) ? 2 : 0 ; /// Simulates an error on position 13
2016-10-27 12:27:37 +00:00
2015-08-11 06:50:32 +00:00
2016-10-27 12:27:37 +00:00
byte [ ] buf = new byte [ 200 ] ;
///
fixed ( byte * pBuf = buf )
2015-08-11 06:50:32 +00:00
{
2016-10-27 12:27:37 +00:00
int retv ;
2017-05-31 12:51:26 +00:00
if ( iperlHead . RfidComPortNr > 0 )
2016-10-27 12:27:37 +00:00
{
retv = readRequestPort1 ( messageID , offset , lenght , pBuf , timeout ) ;
}
else
{
2017-05-31 12:51:26 +00:00
switch ( iperlHead . MuxBoardNr )
2016-04-18 11:38:13 +00:00
{
2016-10-27 12:27:37 +00:00
default :
case 1 : retv = readRequestPort1 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 2 : retv = readRequestPort2 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 3 : retv = readRequestPort3 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 4 : retv = readRequestPort4 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
2016-04-18 11:38:13 +00:00
}
2016-10-27 12:27:37 +00:00
}
2015-08-19 11:04:47 +00:00
2015-08-11 06:50:32 +00:00
for ( int i = 0 ; i < lenght ; i + + ) buffer [ i ] = buf [ i ] ;
2015-09-16 14:30:30 +00:00
2016-10-27 12:27:37 +00:00
///
/// Logging
///
2017-05-31 12:51:26 +00:00
string name = string . Format ( "{0}({1})" , iperlHead . Name , iperlHead . SerialNr ) ;
if ( ( messageID = = MessageID . Configuration ) & & ( offset = = 0 ) & & ( lenght = = ConfigStruct . Length ) )
rfidDataLogger . InfoFormat ( "{0}: ReadRequestPort({1},...) returned {2} {3}" , name , messageID , retv , ( retv ! = 0 ) ? "!" : ConfigStruct . FromByteArray ( buffer ) . ToString ( ) ) ;
else if ( ( messageID = = MessageID . Calibration ) & & ( offset = = 0 ) & & ( lenght = = CalibrationStruct . Length ) )
rfidDataLogger . InfoFormat ( "{0}: ReadRequestPort({1},...) returned {2} {3}" , name , messageID , retv , ( retv ! = 0 ) ? "!" : CalibrationStruct . FromByteArray ( buffer ) . ToString ( ) ) ;
2016-10-27 12:27:37 +00:00
else if ( ( messageID = = MessageID . Calibration ) & & ( offset = = 2 ) & & ( lenght = = 2 ) )
rfidDataLogger . InfoFormat ( "{0}: ReadRequestPort({1},2,2,...) returned {2} {3}" , name , messageID , retv , ( retv ! = 0 ) ? "!" : string . Format ( "Cal={0}" , buf [ 0 ] + 256 * buf [ 1 ] ) ) ;
else
2015-09-21 14:29:12 +00:00
rfidDataLogger . InfoFormat ( "{0}: ReadRequestPort({1}, {2}, {3}, ...) returned {4} {5}" , name , messageID , offset , lenght , retv , ( retv ! = 0 ) ? "!" : "" ) ;
2015-08-11 06:50:32 +00:00
2016-10-27 12:27:37 +00:00
return retv ;
}
2015-08-11 06:50:32 +00:00
}
/// <summary>
/// Wrapper function with safe interface adn unsafe body
/// </summary>
/// <returns>Value returned by writeRequestPort(...)</returns>
2017-05-31 12:51:26 +00:00
public static unsafe int WriteRequestPort ( IperlHead iperlHead , MessageID messageID , int offset , int lenght , byte [ ] buffer , int timeout )
2015-08-11 06:50:32 +00:00
{
2017-05-31 12:51:26 +00:00
if ( iperlHead . DebugLevel ! = DebugMode . Normal ) return 0 ;
2016-10-27 12:27:37 +00:00
2015-08-11 06:50:32 +00:00
fixed ( byte * pBuf = buffer )
{
2016-10-27 12:27:37 +00:00
int retv ;
2017-05-31 12:51:26 +00:00
if ( iperlHead . RfidComPortNr > 0 )
2016-10-27 12:27:37 +00:00
{
retv = writeRequestPort1 ( messageID , offset , lenght , pBuf , timeout ) ;
}
else
{
2017-05-31 12:51:26 +00:00
switch ( iperlHead . MuxBoardNr )
2016-04-18 11:38:13 +00:00
{
2016-10-27 12:27:37 +00:00
default :
case 1 : retv = writeRequestPort1 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 2 : retv = writeRequestPort2 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 3 : retv = writeRequestPort3 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
case 4 : retv = writeRequestPort4 ( messageID , offset , lenght , pBuf , timeout ) ; break ;
2016-04-18 11:38:13 +00:00
}
2016-10-27 12:27:37 +00:00
}
2015-08-19 11:04:47 +00:00
2016-10-27 12:27:37 +00:00
Thread . Sleep ( 250 ) ;
///
/// Logging
///
2017-05-31 12:51:26 +00:00
string name = string . Format ( "{0}({1})" , iperlHead . Name , iperlHead . SerialNr ) ;
2016-10-27 12:27:37 +00:00
if ( lenght = = 1 )
2015-09-21 14:29:12 +00:00
rfidDataLogger . InfoFormat ( "{0}: WriteRequestPort({2}, {3}, {4}, {5}) returned {1} {6}" , name , retv , messageID , offset , lenght , pBuf [ 0 ] . ToString ( "X2" ) , ( retv ! = 0 ) ? "!" : "" ) ;
2015-08-15 21:01:26 +00:00
else if ( lenght = = 2 )
{
2015-09-16 14:30:30 +00:00
if ( messageID = = MessageID . Calibration & & offset = = 2 )
{
UInt16 calibFactor = ( UInt16 ) ( pBuf [ 0 ] + 256 * pBuf [ 1 ] ) ;
2015-09-21 14:29:12 +00:00
rfidDataLogger . InfoFormat ( "{0}: WriteRequestPort(calibFactor={1}) returned {2} {3}" , name , calibFactor , retv , ( retv ! = 0 ) ? "!" : "" ) ;
2015-09-16 14:30:30 +00:00
}
else
2015-09-21 14:29:12 +00:00
rfidDataLogger . InfoFormat ( "{0}: WriteRequestPort({2}, {3}, {4}, {5} {6}) returned {1} {7}" , name , retv , messageID , offset , lenght , pBuf [ 0 ] . ToString ( "X2" ) , pBuf [ 1 ] . ToString ( "X2" ) , ( retv ! = 0 ) ? "!" : "" ) ;
2015-08-15 21:01:26 +00:00
}
else
2015-09-21 14:29:12 +00:00
rfidDataLogger . InfoFormat ( "{0}: WriteRequestPort({2}, {3}, {4}, {5} {6} ...) returned {1} {7}" , name , retv , messageID , offset , lenght , pBuf [ 0 ] . ToString ( "X2" ) , pBuf [ 1 ] . ToString ( "X2" ) , ( retv ! = 0 ) ? "!" : "" ) ;
2016-10-27 12:27:37 +00:00
return retv ;
2015-08-15 21:01:26 +00:00
}
2015-08-11 06:50:32 +00:00
}
#endregion DLL_Interface
2015-08-14 17:20:47 +00:00
const string ReadConfigurationStr = "Read configuration" ; /// Example: "Read configuration" or "Read configuration if enabled"
const string SetTestModeStr = "Set Test mode" ; /// Example: "Set Test mode" or "Set Test mode A0" (hexadecimal number is the required 'testModeConfig'
2015-08-14 12:33:36 +00:00
const string SetActiveModeStr = "Set Active mode" ;
const string ReadCalibrationStr = "Read calibration" ;
const string WriteCalibrationFactorStr = "Write calibration factor" ;
2016-11-02 12:16:07 +00:00
const string NormalizeCalibrationFactorStr = "Normalize calibration factor" ;
2015-08-14 12:33:36 +00:00
const string ResetQ2CorrectionStr = "Reset Q2 correction" ;
const string WriteQ2CorrectionStr = "Write Q2 correction" ;
2017-03-19 21:03:31 +00:00
const string WriteQ2CorrectionAltStr = "Write Q2 correction Alt" ;
2017-07-14 14:31:35 +00:00
const string WriteQ2CorrectionGreeceStr = "Write Q2 correction Greece" ;
2016-02-16 13:44:10 +00:00
const string Reset2HzCorrectionStr = "Reset 2Hz correction" ;
const string Write2HzCorrectionStr = "Write 2Hz correction" ;
2015-08-14 12:33:36 +00:00
2015-08-11 06:50:32 +00:00
2016-01-08 18:18:45 +00:00
DateTime startTime ;
int startTimeSec ;
2015-08-11 06:50:32 +00:00
// Set to 'true' when the form closes
public bool Completed { get { return formCompleted ; } }
bool formCompleted ;
/// <summary> Number of text boxes for serial numbers </summary>
2016-01-19 16:38:09 +00:00
public int WaterMetersCount ;
2015-08-11 06:50:32 +00:00
int textBoxesCount ;
Label [ ] labels ;
2016-06-27 13:24:10 +00:00
PictureBox [ ] counters ;
2015-08-11 06:50:32 +00:00
TextBox [ ] messages ;
2017-05-31 12:51:26 +00:00
static IList < IperlHead > iperlHeads ;
2017-02-14 14:41:50 +00:00
static IList < int > waterMeterPositions ; /// keeps original indices in RegisterReaders list
2015-09-04 11:49:04 +00:00
Modbus . QuidoRS . QuidoRS quido ;
2015-08-11 06:50:32 +00:00
///
/// RFID multiplexer PCB / RFID serial port and worker thread related variables
///
2015-09-04 11:49:04 +00:00
static TestMethodCfg cfg ;
2016-01-19 16:38:09 +00:00
static IList < Config . Entities . Test > tests ;
2015-09-04 11:49:04 +00:00
static IList < iPerlCommunicationParams > multiTestParams ;
static int currentActivityStep ;
static int currentGroup ; /// form -> worker thread (0 = none)
2015-08-11 06:50:32 +00:00
static int lastGroup ;
2015-08-12 14:05:06 +00:00
static int completedCommCount ; /// Number of completed communication steps
2015-08-11 06:50:32 +00:00
static IList < Thread > workerThreads ;
static IList < int > rfidPortNrs ;
2015-09-04 11:49:04 +00:00
static bool stopWorkerThreads ; /// form -> worker thread
2015-08-11 06:50:32 +00:00
2015-09-04 11:49:04 +00:00
/// <summary> Parameterless constructor (without watermeters, threads) </summary>
2015-08-11 06:50:32 +00:00
public iPerlCommunicationForm ( )
{
InitializeComponent ( ) ;
textBoxesCount = 48 ;
labels = new Label [ 48 ]
{
wmLabel1 , wmLabel2 , wmLabel3 , wmLabel4 , wmLabel5 ,
wmLabel6 , wmLabel7 , wmLabel8 , wmLabel9 , wmLabel10 ,
wmLabel11 , wmLabel12 , wmLabel13 , wmLabel14 , wmLabel15 ,
wmLabel16 , wmLabel17 , wmLabel18 , wmLabel19 , wmLabel20 ,
wmLabel21 , wmLabel22 , wmLabel23 , wmLabel24 , wmLabel25 ,
wmLabel26 , wmLabel27 , wmLabel28 , wmLabel29 , wmLabel30 ,
wmLabel31 , wmLabel32 , wmLabel33 , wmLabel34 , wmLabel35 ,
wmLabel36 , wmLabel37 , wmLabel38 , wmLabel39 , wmLabel40 ,
wmLabel41 , wmLabel42 , wmLabel43 , wmLabel44 , wmLabel45 ,
wmLabel46 , wmLabel47 , wmLabel48 ,
} ;
2016-06-27 13:24:10 +00:00
counters = new PictureBox [ 48 ]
2015-09-21 14:29:12 +00:00
{
2016-06-27 13:24:10 +00:00
pictureBox1 , pictureBox2 , pictureBox3 , pictureBox4 , pictureBox5 ,
pictureBox6 , pictureBox7 , pictureBox8 , pictureBox9 , pictureBox10 ,
pictureBox11 , pictureBox12 , pictureBox13 , pictureBox14 , pictureBox15 ,
pictureBox16 , pictureBox17 , pictureBox18 , pictureBox19 , pictureBox20 ,
pictureBox21 , pictureBox22 , pictureBox23 , pictureBox24 , pictureBox25 ,
pictureBox26 , pictureBox27 , pictureBox28 , pictureBox29 , pictureBox30 ,
pictureBox31 , pictureBox32 , pictureBox33 , pictureBox34 , pictureBox35 ,
pictureBox36 , pictureBox37 , pictureBox38 , pictureBox39 , pictureBox40 ,
pictureBox41 , pictureBox42 , pictureBox43 , pictureBox44 , pictureBox45 ,
pictureBox46 , pictureBox47 , pictureBox48 ,
2015-09-21 14:29:12 +00:00
} ;
2015-08-11 06:50:32 +00:00
messages = new TextBox [ 48 ]
{
wmTextBox1 , wmTextBox2 , wmTextBox3 , wmTextBox4 , wmTextBox5 ,
wmTextBox6 , wmTextBox7 , wmTextBox8 , wmTextBox9 , wmTextBox10 ,
wmTextBox11 , wmTextBox12 , wmTextBox13 , wmTextBox14 , wmTextBox15 ,
wmTextBox16 , wmTextBox17 , wmTextBox18 , wmTextBox19 , wmTextBox20 ,
wmTextBox21 , wmTextBox22 , wmTextBox23 , wmTextBox24 , wmTextBox25 ,
wmTextBox26 , wmTextBox27 , wmTextBox28 , wmTextBox29 , wmTextBox30 ,
wmTextBox31 , wmTextBox32 , wmTextBox33 , wmTextBox34 , wmTextBox35 ,
wmTextBox36 , wmTextBox37 , wmTextBox38 , wmTextBox39 , wmTextBox40 ,
wmTextBox41 , wmTextBox42 , wmTextBox43 , wmTextBox44 , wmTextBox45 ,
wmTextBox46 , wmTextBox47 , wmTextBox48 ,
} ;
2017-05-31 12:51:26 +00:00
/// Initialize lists
iperlHeads = new List < IperlHead > ( ) ;
waterMeterPositions = new List < int > ( ) ;
formCompleted = false ;
2015-08-11 06:50:32 +00:00
2016-01-08 18:18:45 +00:00
startTime = DateTime . Now ;
startTimeSec = StateMachine . Time ;
2015-08-11 06:50:32 +00:00
/// Find QuidoRS
foreach ( var comp in StateMachine . Components )
{
if ( comp is Modbus . QuidoRS . QuidoRS )
{
quido = comp as Modbus . QuidoRS . QuidoRS ;
break ;
}
}
/// Attach to 'CommCompleted' handler
CommCompletedHandler + = delegate ( object sender , CommCompletedEventArgs args )
{
if ( InvokeRequired )
{
Invoke ( new EventHandler < CommCompletedEventArgs > ( DoOnCommCompleted ) , sender , args ) ;
}
else DoOnCommCompleted ( sender , args ) ;
} ;
/// Attach to 'AllCompleted' handler
AllCompletedHandler + = delegate ( object sender , AllCompletedEventArgs args )
{
if ( InvokeRequired )
{
Invoke ( new EventHandler < AllCompletedEventArgs > ( DoOnAllCompleted ) , sender , args ) ;
}
else DoOnAllCompleted ( sender , args ) ;
} ;
2015-09-05 22:09:52 +00:00
StartForceCloseHandler ( ) ;
2015-08-11 06:50:32 +00:00
}
2015-09-04 11:49:04 +00:00
2015-08-11 06:50:32 +00:00
/// <summary>
2016-01-19 16:38:09 +00:00
/// Constructor for one iPerlCommunication 'test'
2015-08-11 06:50:32 +00:00
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
2016-01-19 16:38:09 +00:00
public iPerlCommunicationForm ( TestMethodCfg cfg , Test test , iPerlCommunicationParams testParams )
: this ( )
{
iPerlCommunicationForm . cfg = cfg ;
iPerlCommunicationForm . tests = new List < Test > ( ) ;
iPerlCommunicationForm . tests . Add ( test ) ;
iPerlCommunicationForm . multiTestParams = new List < iPerlCommunicationParams > ( ) ;
iPerlCommunicationForm . multiTestParams . Add ( testParams ) ;
2016-02-13 15:40:26 +00:00
ProcessData . RegisterReaders = StateMachine . GetMetersPath ( test ) . RegisterReaders ;
2016-01-19 16:38:09 +00:00
activityLabel . Text = testParams . Activity ;
ConstructorCommon ( ) ;
}
/// <summary>
/// Constructor for multiple iPerlCommunication 'tests'
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public iPerlCommunicationForm ( TestMethodCfg cfg , IList < Test > tests , IList < iPerlCommunicationParams > multiTestParams )
2015-08-11 06:50:32 +00:00
: this ( )
2015-09-04 11:49:04 +00:00
{
2015-09-06 21:36:14 +00:00
iPerlCommunicationForm . cfg = cfg ;
2016-01-19 16:38:09 +00:00
iPerlCommunicationForm . tests = tests ;
iPerlCommunicationForm . multiTestParams = multiTestParams ;
2015-09-06 21:36:14 +00:00
2016-01-19 16:38:09 +00:00
if ( multiTestParams . Count > 0 )
{
2016-02-13 15:40:26 +00:00
ProcessData . RegisterReaders = StateMachine . GetMetersPath ( tests [ 0 ] ) . RegisterReaders ;
2016-01-19 16:38:09 +00:00
activityLabel . Text = multiTestParams [ 0 ] . Activity ;
}
ConstructorCommon ( ) ;
}
void ConstructorCommon ( )
{
2017-02-14 14:41:50 +00:00
for ( int wmPos = 0 ; wmPos < ProcessData . RegisterReaders . Length ; wmPos + + )
2015-09-04 11:49:04 +00:00
{
2017-05-31 12:51:26 +00:00
IperlHead iperlHead = ProcessData . RegisterReaders [ wmPos ] as IperlHead ;
2017-02-14 14:41:50 +00:00
2017-05-31 12:51:26 +00:00
if ( iperlHead ! = null )
2016-04-19 08:10:51 +00:00
{
2017-05-31 12:51:26 +00:00
iperlHeads . Add ( iperlHead ) ;
2017-02-14 14:41:50 +00:00
waterMeterPositions . Add ( wmPos ) ;
2016-04-19 08:10:51 +00:00
}
2015-09-04 11:49:04 +00:00
}
2017-05-31 12:51:26 +00:00
WaterMetersCount = iperlHeads . Count ;
2016-01-19 16:38:09 +00:00
2016-04-19 08:10:51 +00:00
ShuffleTextBoxes ( WaterMetersCount , Config . Data . LineSize ) ;
2015-09-04 11:49:04 +00:00
///
/// Prepare worker threads, 'rfidPortNrs', 'lastGroup', etc..
///
workerThreads = new List < Thread > ( ) ;
rfidPortNrs = new List < int > ( ) ;
currentActivityStep = 0 ;
currentGroup = 0 ;
lastGroup = 0 ; /// group numbers are >=1, lastGroup == 0 means no group
completedCommCount = 0 ;
stopWorkerThreads = false ;
2017-05-31 12:51:26 +00:00
foreach ( var iPerl in iPerlCommunicationForm . iperlHeads )
2015-09-04 11:49:04 +00:00
{
if ( ! rfidPortNrs . Contains ( iPerl . MuxBoardNr ) )
{
rfidPortNrs . Add ( iPerl . MuxBoardNr ) ;
2015-09-06 21:36:14 +00:00
if ( workerThreads . Count < cfg . NrThreads )
2015-09-04 11:49:04 +00:00
{
Thread thread = new Thread ( iPerlCommunicationForm . Worker ) ;
workerThreads . Add ( thread ) ;
}
}
2015-09-11 12:15:32 +00:00
2015-09-04 11:49:04 +00:00
if ( iPerl . Group > lastGroup ) lastGroup = iPerl . Group ;
}
2016-04-19 08:10:51 +00:00
StringBuilder sb = new StringBuilder ( ) ;
2016-04-20 13:03:18 +00:00
sb . Append ( "rfidPortNrs = [" ) ;
2016-04-19 08:10:51 +00:00
foreach ( var v in rfidPortNrs ) sb . Append ( string . Format ( " {0}" , v ) ) ;
2016-04-20 13:03:18 +00:00
sb . Append ( string . Format ( " ], nrThreads = {0}" , workerThreads . Count ) ) ;
2016-04-19 08:10:51 +00:00
log . WarnFormat ( sb . ToString ( ) ) ;
2015-09-04 11:49:04 +00:00
}
2015-08-11 06:50:32 +00:00
/// <summary>
/// Make sure the layout of labels/text boxes on the screen
/// corresponds to the layout of watermeters of the test bench.
/// </summary>
/// <param name="wmsCount">Number of watermeters</param>
/// <param name="lineSize">Number of watermeters in one line</param>
void ShuffleTextBoxes ( int wmsCount , int lineSize )
{
if ( wmsCount < textBoxesCount & & lineSize > 0 )
{
int nrLines = ( wmsCount + lineSize - 1 ) / lineSize ;
int gap = ( textBoxesCount - wmsCount ) / nrLines ;
int dest = 0 ;
for ( int l = 0 ; l < nrLines ; l + + )
{
for ( int i = 0 ; i < lineSize ; i + + )
{
labels [ dest ] = labels [ l * lineSize + l * gap + i ] ;
2015-09-21 14:29:12 +00:00
counters [ dest ] = counters [ l * lineSize + l * gap + i ] ;
2015-08-11 06:50:32 +00:00
messages [ dest ] = messages [ l * lineSize + l * gap + i ] ;
dest + + ;
}
}
textBoxesCount = wmsCount ;
}
2016-04-23 12:32:15 +00:00
///
/// Resize the dialog to fit the enabled controls
///
int xMax = 0 ;
int yMax = 0 ;
for ( int i = 0 ; i < textBoxesCount ; i + + )
{
if ( messages [ i ] . Left + messages [ i ] . Width > xMax ) xMax = messages [ i ] . Left + messages [ i ] . Width ;
if ( messages [ i ] . Top + messages [ i ] . Height > yMax ) yMax = messages [ i ] . Top + messages [ i ] . Height ;
}
Width = xMax + 30 ;
Height = yMax + 50 ;
2015-08-11 06:50:32 +00:00
}
2016-04-23 12:32:15 +00:00
void Localize ( )
2015-08-11 06:50:32 +00:00
{
Text = Strings . Water_Meter_States ;
2017-05-31 12:51:26 +00:00
for ( int i = 0 ; i < Math . Min ( textBoxesCount , iperlHeads . Count ) ; i + + )
2015-08-11 06:50:32 +00:00
{
2017-05-31 12:51:26 +00:00
labels [ i ] . Text = iperlHeads [ i ] . Name ;
2015-08-11 06:50:32 +00:00
}
}
2015-09-04 11:49:04 +00:00
2015-08-11 06:50:32 +00:00
private void iPerlCommunicationForm_Load ( object sender , EventArgs e )
{
Localize ( ) ;
//Height = 50 + 90 * WaterMetersCount;
for ( int i = 0 ; i < textBoxesCount ; i + + )
{
2015-09-11 12:15:32 +00:00
//if (disabled != null && i < disabled.Length && disabled[i])
//{
// labels[i].Visible = messages[i].Visible = false;
//}
//else
2015-08-11 06:50:32 +00:00
{
2015-09-21 14:29:12 +00:00
labels [ i ] . Visible = counters [ i ] . Visible = messages [ i ] . Visible = true ;
2015-08-11 06:50:32 +00:00
messages [ i ] . Text = "---" ;
}
}
2015-09-05 22:09:52 +00:00
TBF . LocalSettings ls = Program . LocalSettings ;
Left = ( ls . iPerlCommunicationsFormLeft ! = 0 ) ? ls . iPerlCommunicationsFormLeft : 150 ;
Top = ( ls . iPerlCommunicationsFormTop ! = 0 ) ? ls . iPerlCommunicationsFormTop : 150 ;
2015-08-19 11:04:47 +00:00
2015-09-21 14:29:12 +00:00
/// Reset opto-data indication
2017-05-31 12:51:26 +00:00
for ( int i = 0 ; i < iperlHeads . Count ; i + + )
2015-09-21 14:29:12 +00:00
{
2017-05-31 12:51:26 +00:00
iperlHeads [ i ] . FlushedDataCount = 0 ;
2016-06-27 13:24:10 +00:00
counters [ i ] . BackColor = Color . Red ;
2015-09-21 14:29:12 +00:00
}
2015-09-05 22:09:52 +00:00
///
/// Start worker threads, etc.
///
if ( workerThreads ! = null )
{
int wtId = 0 ;
foreach ( var wt in workerThreads ) wt . Start ( new Boxes . IntBox ( wtId + + ) ) ;
///
/// Set QuidoRS outputs and start the whole communication process
/// by incrementing 'currentGroup'.
///
if ( quido ! = null )
{
quido . SetOutputs ( ( ushort ) ( 16 - currentGroup - 1 ) ) ;
Thread . Sleep ( 200 ) ;
}
currentGroup + + ;
}
2015-08-11 06:50:32 +00:00
}
2015-09-04 11:49:04 +00:00
2015-08-11 06:50:32 +00:00
private void NormalClose ( )
{
CommCompletedHandler = null ;
AllCompletedHandler = null ;
2017-02-14 14:41:50 +00:00
if ( multiTestParams ! = null & &
multiTestParams . Count > 0 & &
! multiTestParams [ 0 ] . SimultWithNext ) /// RFID Communication at the end of the cycle does not influence the result
2016-02-08 16:03:07 +00:00
{
UpdateRfidCommResult ( tests ) ; /// TODO: Pass the test info in a correct way
}
2016-01-03 01:05:35 +00:00
2015-08-11 06:50:32 +00:00
formCompleted = true ;
2015-08-19 11:04:47 +00:00
Program . LocalSettings . iPerlCommunicationsFormLeft = Location . X ;
Program . LocalSettings . iPerlCommunicationsFormTop = Location . Y ;
Program . LocalSettings . Save ( ) ;
2015-08-11 06:50:32 +00:00
DialogResult = DialogResult . OK ;
Close ( ) ;
}
#region Forced close handling
public void StartForceCloseHandler ( )
{
UiBridge . Bridge . CloseModelessFormHandler + = delegate ( object sender , EventArgs args )
{
if ( InvokeRequired ) { Invoke ( new EventHandler < EventArgs > ( OnForceClose ) , sender , args ) ; }
else OnForceClose ( sender , args ) ;
} ;
}
void OnForceClose ( object sender , EventArgs args )
{
CommCompletedHandler = null ;
AllCompletedHandler = null ;
2015-09-04 11:49:04 +00:00
stopWorkerThreads = true ;
2015-08-11 06:50:32 +00:00
DialogResult = DialogResult . Cancel ;
Close ( ) ;
}
#endregion
2015-08-15 15:51:54 +00:00
/// <summary>
/// Worker thread
/// </summary>
/// <param name="threadData">Thread ID (integer) wrapped into IntBox</param>
2015-08-12 14:05:06 +00:00
static void Worker ( object threadData )
2015-08-11 06:50:32 +00:00
{
2015-08-12 14:05:06 +00:00
int threadId = ( threadData as Boxes . IntBox ) . Val ;
2015-08-11 06:50:32 +00:00
2015-09-04 11:49:04 +00:00
int activityStep = 0 ; /// activity step > 0 in case multiTestParams are used
2015-08-15 21:01:26 +00:00
2016-01-08 18:18:45 +00:00
for ( int i = 0 ; i < multiTestParams . Count ; i + + )
2015-09-04 11:49:04 +00:00
{
2016-01-08 18:18:45 +00:00
iPerlCommunicationParams testParams = multiTestParams [ i ] ;
2017-05-05 10:41:15 +00:00
TBF . UiBridge . TestProgressEventArgs . SetEstimatedTimes ( new int [ ] { 0 , 0 , 10 , 0 , 140 , 0 , 0 , 0 } ) ;
2016-01-19 16:38:09 +00:00
TBF . UiBridge . Bridge . OnTestProgress ( null , new TBF . UiBridge . TestProgressEventArgs ( tests [ i ] , Config . Entities . Progress . JustStarted ) ) ;
2016-01-08 18:18:45 +00:00
2015-09-04 11:49:04 +00:00
string activity = testParams . Activity ; /// Current activity
2015-08-11 06:50:32 +00:00
2015-09-04 11:49:04 +00:00
if ( threadId = = 0 )
{
rfidDataLogger . InfoFormat ( "" ) ; /// Makes the log more readable when there is a lot of data
rfidDataLogger . WarnFormat ( "Activity = {0}" , activity ) ;
rfidDataLogger . InfoFormat ( "" ) ; /// Makes the log more readable when there is a lot of data
}
2015-08-12 14:05:06 +00:00
2015-09-04 11:49:04 +00:00
for ( int group = 1 ; group < = lastGroup ; group + + )
{
/// Synchronize with QuidoRS and other threads
2015-09-05 22:09:52 +00:00
while ( ( ( group ! = currentGroup ) | | ( activityStep ! = currentActivityStep ) ) & & ! stopWorkerThreads )
2015-09-04 11:49:04 +00:00
{
Thread . Sleep ( 50 ) ;
}
if ( stopWorkerThreads ) break ;
2015-09-06 21:36:14 +00:00
for ( int rfidPortIx = threadId ; rfidPortIx < threadId + 4 ; rfidPortIx + = cfg . NrThreads )
2015-09-04 11:49:04 +00:00
{
2016-03-01 17:57:36 +00:00
if ( rfidPortIx > = rfidPortNrs . Count ) break ; // quit, all RFID ports of all water meters done
2015-09-04 11:49:04 +00:00
int rfidPortNr = rfidPortNrs [ rfidPortIx ] ;
int wmNr = 0 ;
bool wmFound = false ;
2017-05-31 12:51:26 +00:00
for ( int j = 0 ; j < iperlHeads . Count ; j + + )
2015-09-04 11:49:04 +00:00
{
2017-05-31 12:51:26 +00:00
IperlHead ihead = iperlHeads [ j ] ;
if ( ( ihead . MuxBoardNr = = rfidPortNr ) & & ( ihead . Group = = group ) )
2015-09-04 11:49:04 +00:00
{
wmFound = true ;
2017-07-18 06:33:20 +00:00
Results . Entities . WaterMeter wm = ProcessData . BatchRslts . WaterMeters [ waterMeterPositions [ j ] ] ;
2015-09-04 11:49:04 +00:00
CommErr error ;
string resultStr = string . Empty ;
2017-05-31 12:51:26 +00:00
if ( activity . ToLower ( ) . Contains ( ReadConfigurationStr . ToLower ( ) ) ) error = ReadConfiguration ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Contains ( SetTestModeStr . ToLower ( ) ) ) error = SetTestMode ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Equals ( SetActiveModeStr . ToLower ( ) ) ) error = SetActiveMode ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Equals ( ReadCalibrationStr . ToLower ( ) ) ) error = ReadCalibration ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Contains ( WriteCalibrationFactorStr . ToLower ( ) ) ) error = WriteCalibrationFactor ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Equals ( NormalizeCalibrationFactorStr . ToLower ( ) ) ) error = NormalizeCalibrationFactor ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Equals ( ResetQ2CorrectionStr . ToLower ( ) ) ) error = ResetQ2Correction ( ihead , wm , ref resultStr ) ;
2017-07-14 14:31:35 +00:00
else if ( activity . ToLower ( ) . Equals ( WriteQ2CorrectionStr . ToLower ( ) ) )
{
error = WriteQ2Correction ( ihead , wm , ref resultStr , Q2CorrType . Standard , null , false ) ;
}
else if ( activity . ToLower ( ) . Equals ( WriteQ2CorrectionAltStr . ToLower ( ) ) )
{
error = WriteQ2Correction ( ihead , wm , ref resultStr , Q2CorrType . Dewa , null , false ) ;
}
else if ( activity . ToLower ( ) . Contains ( WriteQ2CorrectionGreeceStr . ToLower ( ) ) )
{
error = WriteQ2Correction ( ihead , wm , ref resultStr , Q2CorrType . Greece , activity . Substring ( WriteQ2CorrectionGreeceStr . Length ) . Trim ( ) , true ) ;
}
2017-05-31 12:51:26 +00:00
else if ( activity . ToLower ( ) . Equals ( Reset2HzCorrectionStr . ToLower ( ) ) ) error = Reset2HzCorrection ( ihead , wm , ref resultStr ) ;
else if ( activity . ToLower ( ) . Equals ( Write2HzCorrectionStr . ToLower ( ) ) ) error = Write2HzCorrection ( ihead , wm , ref resultStr ) ;
2015-09-04 11:49:04 +00:00
else
{
error = CommErr . None ;
resultStr = "Invalid activity" ;
}
2015-09-05 22:09:52 +00:00
if ( error = = CommErr . None )
{
OnCommCompleted ( null , new CommCompletedEventArgs ( threadId , wmNr , resultStr ) ) ;
}
2017-05-31 12:51:26 +00:00
else if ( ihead . CommFailed | | error = = CommErr . CommFailed )
2015-09-05 22:09:52 +00:00
{
OnCommCompleted ( null , new CommCompletedEventArgs ( threadId , wmNr , "Watermeter is disabled" ) ) ;
}
2015-09-04 11:49:04 +00:00
else
{
OnCommCompleted ( null , new CommCompletedEventArgs ( threadId , wmNr , string . Format ( "{0} failed ({1}) !!!" , activity , error ) ) ) ;
2017-05-31 12:51:26 +00:00
rfidDataLogger . ErrorFormat ( "Group={0}, Board={1}, {2} failed ({3}) !!!" , currentGroup , ihead . MuxBoardNr , activity , error ) ;
ihead . CommFailed = true ;
2015-09-04 11:49:04 +00:00
}
break ;
}
wmNr + + ;
2017-05-31 12:51:26 +00:00
TBF . UiBridge . Bridge . OnTestProgress ( null , new TBF . UiBridge . TestProgressEventArgs ( tests [ i ] , Config . Entities . Progress . FlowSetting ) ) ;
2015-09-04 11:49:04 +00:00
}
2016-01-08 18:18:45 +00:00
if ( ! wmFound )
{
OnCommCompleted ( null , new CommCompletedEventArgs ( threadId , - 1 , string . Empty ) ) ; /// Send negative wmNr
}
2015-09-04 11:49:04 +00:00
if ( stopWorkerThreads ) break ;
}
if ( stopWorkerThreads ) break ;
} /// for (int group
2016-01-19 16:38:09 +00:00
TBF . UiBridge . Bridge . OnTestProgress ( null , new TBF . UiBridge . TestProgressEventArgs ( tests [ i ] , Config . Entities . Progress . Completed ) ) ;
2015-09-04 11:49:04 +00:00
activityStep + + ;
if ( stopWorkerThreads ) break ;
}
2015-08-11 06:50:32 +00:00
}
2015-08-15 15:51:54 +00:00
2015-08-14 09:38:53 +00:00
/// <summary>
/// Read a complete configuration structure of the watermeter
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr ReadConfiguration ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-11 06:50:32 +00:00
{
2015-08-14 17:20:47 +00:00
///
/// The activity is "Read configuration" (this enables the watermeter, resets error flag)
/// or "Read configuration if enabled" (this keeps th error flag).
///
2015-09-04 11:49:04 +00:00
if ( ! multiTestParams [ currentActivityStep ] . Activity . ToLower ( ) . Contains ( " if enabled" ) )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
ihead . CommFailed = false ;
2015-08-15 15:51:54 +00:00
}
2015-08-11 06:50:32 +00:00
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2015-08-14 09:38:53 +00:00
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2015-08-11 06:50:32 +00:00
2015-08-17 14:02:30 +00:00
CommErr error = CommErr . Read ;
2015-08-11 06:50:32 +00:00
2015-08-15 15:51:54 +00:00
/// Read configuration
byte [ ] config = null ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-11 06:50:32 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Configuration , 0 , ConfigStruct . Length , out config , cfg . CommTimeout ) )
2015-08-15 15:51:54 +00:00
{
2015-08-17 14:02:30 +00:00
error = CommErr . None ;
2017-05-31 12:51:26 +00:00
ihead . ConfigStruct = ConfigStruct . FromByteArray ( config ) ;
resultStr = ihead . ConfigStruct . ToString ( 1 ) ;
2015-08-15 15:51:54 +00:00
break ;
}
2015-08-11 06:50:32 +00:00
}
2015-08-15 15:51:54 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-11 06:50:32 +00:00
}
2015-08-15 15:51:54 +00:00
2015-08-14 09:38:53 +00:00
/// <summary>
2015-08-14 12:33:36 +00:00
/// Set the watermeter to the test mode.
/// If testModeConfig is specified as a hexadeximal number appended to "set test mode ", it is verified
/// whether the testModeConfig is correctly set, if necessary it is changed to the specified value.
/// Read a part of configuration afterwards to verify the mode was set correctly.
2015-08-14 09:38:53 +00:00
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr SetTestMode ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-11 06:50:32 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2015-08-15 15:51:54 +00:00
Byte testModeConfig = 0xA0 ; /// Default value
///
2015-09-04 11:49:04 +00:00
if ( multiTestParams [ currentActivityStep ] . Activity . Length > SetTestModeStr . Length )
2015-08-11 06:50:32 +00:00
{
2015-09-04 11:49:04 +00:00
string testModeConfigStr = multiTestParams [ currentActivityStep ] . Activity . Substring ( SetTestModeStr . Length + 1 ) ;
2015-08-15 15:51:54 +00:00
UInt16 byteVal ;
if ( UInt16 . TryParse ( testModeConfigStr , NumberStyles . HexNumber , CultureInfo . CurrentCulture , out byteVal ) & & byteVal < = 255 )
2015-08-11 06:50:32 +00:00
{
2015-08-15 15:51:54 +00:00
testModeConfig = ( Byte ) byteVal ; /// Update with specified value
2015-08-14 12:33:36 +00:00
}
2015-08-15 15:51:54 +00:00
}
2015-08-14 12:33:36 +00:00
2017-05-31 12:51:26 +00:00
if ( ihead . ConfigStruct . MeterState = = MeterState . Test & & ihead . ConfigStruct . TestModeConfig = = testModeConfig )
2015-08-15 15:51:54 +00:00
{
/// Already in the correct test mode
2017-05-31 12:51:26 +00:00
resultStr = "Already " + ihead . ConfigStruct . ToString ( 1 ) ;
2015-08-17 14:02:30 +00:00
return CommErr . None ;
2015-08-15 15:51:54 +00:00
}
2015-08-14 12:33:36 +00:00
2015-08-15 15:51:54 +00:00
/// Communication necessary
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2015-08-14 09:38:53 +00:00
2015-08-17 14:02:30 +00:00
CommErr error = CommErr . None ;
2015-08-14 17:20:47 +00:00
2017-05-31 12:51:26 +00:00
if ( error = = CommErr . None & & ( ihead . ConfigStruct . TestModeConfig ! = testModeConfig ) & & ( ihead . ConfigStruct . MeterState ! = MeterState . Active ) )
2015-08-15 15:51:54 +00:00
{
/// Switch to Active mode in order to change TestModeConfig
2015-08-17 14:02:30 +00:00
error = CommErr . CmdActive ;
2015-08-15 15:51:54 +00:00
byte [ ] cmd = new byte [ 1 ] { ( byte ) 6 } ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Command , 0 , 1 , cmd , cfg . CommTimeout ) ) { error = CommErr . None ; break ; }
2015-08-15 15:51:54 +00:00
}
2016-02-16 14:57:30 +00:00
Thread . Sleep ( 250 ) ;
2015-08-15 15:51:54 +00:00
}
2015-08-14 17:20:47 +00:00
2017-05-31 12:51:26 +00:00
if ( error = = CommErr . None & & ( ihead . ConfigStruct . TestModeConfig ! = testModeConfig ) )
2015-08-15 15:51:54 +00:00
{
/// Change the TestModeConfig if necessary
2015-08-17 14:02:30 +00:00
error = CommErr . Write ;
2015-08-15 15:51:54 +00:00
byte [ ] tstMdCfg = new byte [ 1 ] { testModeConfig } ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Configuration , 21 , 1 , tstMdCfg , cfg . CommTimeout ) )
2015-08-14 17:20:47 +00:00
{
2017-05-31 12:51:26 +00:00
ihead . ConfigStruct . Update ( 21 , tstMdCfg ) ;
2015-08-17 14:02:30 +00:00
error = CommErr . None ;
2015-08-15 15:51:54 +00:00
break ;
2015-08-14 17:20:47 +00:00
}
}
2016-02-16 14:57:30 +00:00
Thread . Sleep ( 250 ) ;
2015-08-11 06:50:32 +00:00
}
2015-08-17 14:02:30 +00:00
if ( error = = CommErr . None )
2015-08-11 06:50:32 +00:00
{
2015-08-15 15:51:54 +00:00
/// Switch to test mode
2015-08-17 14:02:30 +00:00
error = CommErr . CmdTest ;
2015-08-15 15:51:54 +00:00
byte [ ] cmd = new byte [ 1 ] { ( byte ) 7 } ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Command , 0 , 1 , cmd , cfg . CommTimeout ) ) { error = CommErr . None ; break ; }
2015-08-15 15:51:54 +00:00
}
2016-02-16 14:57:30 +00:00
Thread . Sleep ( 250 ) ;
2015-08-14 09:38:53 +00:00
}
2015-08-15 15:51:54 +00:00
/// Now the meter should be in the Test mode ... verify
2015-08-17 14:02:30 +00:00
if ( error = = CommErr . None )
2015-08-14 09:38:53 +00:00
{
2015-08-15 15:51:54 +00:00
/// Verify the configuration
2015-08-17 14:02:30 +00:00
error = CommErr . Verify ;
2015-08-15 15:51:54 +00:00
byte [ ] cfg_0_3 = null ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Configuration , 0 , 4 , out cfg_0_3 , cfg . CommTimeout ) )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
ihead . ConfigStruct . Update ( 0 , cfg_0_3 ) ;
if ( ihead . ConfigStruct . MeterState = = MeterState . Test )
2015-08-17 14:02:30 +00:00
{
error = CommErr . None ;
2017-05-31 12:51:26 +00:00
resultStr = ihead . ConfigStruct . ToString ( 1 ) ;
2015-08-17 14:02:30 +00:00
break ;
}
2015-08-15 15:51:54 +00:00
}
}
2015-08-14 09:38:53 +00:00
}
2015-08-15 15:51:54 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-14 09:38:53 +00:00
}
2015-08-11 06:50:32 +00:00
2015-08-15 15:51:54 +00:00
2015-08-14 09:38:53 +00:00
/// <summary>
2015-08-14 12:33:36 +00:00
/// Set the watermeter to the active mode.
2015-08-14 09:38:53 +00:00
/// Read a part of configuration afterwards to verify the mode was set correctly.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr SetActiveMode ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-14 09:38:53 +00:00
{
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
CommErr error = CommErr . CmdActive ;
2015-08-14 09:38:53 +00:00
2015-08-15 15:51:54 +00:00
/// Switch to active mode
byte [ ] cmd = new byte [ 1 ] { ( byte ) 6 } ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-14 09:38:53 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Command , 0 , 1 , cmd , cfg . CommTimeout ) )
2016-02-16 14:57:30 +00:00
{
error = CommErr . None ;
break ;
}
2015-08-15 15:51:54 +00:00
}
2015-08-14 09:38:53 +00:00
2016-10-27 12:27:37 +00:00
#if VERIFY_ACTIVE_MODE
2015-08-17 14:02:30 +00:00
if ( error = = CommErr . None )
2015-08-15 15:51:54 +00:00
{
2015-08-17 14:02:30 +00:00
error = CommErr . Verify ;
2015-08-11 06:50:32 +00:00
2015-08-15 15:51:54 +00:00
/// Read configuration
byte [ ] cfg_0_3 = null ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-14 09:38:53 +00:00
{
2017-07-14 14:31:35 +00:00
if ( ihead . ConfigStruct = = null )
2015-08-14 09:38:53 +00:00
{
2017-07-14 14:31:35 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Configuration , 0 , 4 , out cfg_0_3 , cfg . CommTimeout ) )
2015-08-17 14:02:30 +00:00
{
2017-07-14 14:31:35 +00:00
ihead . ConfigStruct . Update ( 0 , cfg_0_3 ) ;
if ( ihead . ConfigStruct . MeterState = = MeterState . Active )
2016-03-01 15:22:49 +00:00
{
error = CommErr . None ;
2017-07-14 14:31:35 +00:00
resultStr = ihead . ConfigStruct . ToString ( 1 ) ;
2016-03-01 15:22:49 +00:00
break ;
}
2015-08-17 14:02:30 +00:00
}
2015-08-14 09:38:53 +00:00
}
}
}
2016-02-16 14:57:30 +00:00
#else
if ( error = = CommErr . None )
{
2017-05-31 12:51:26 +00:00
if ( ihead . ConfigStruct = = null )
2016-03-01 15:22:49 +00:00
resultStr = "OK (Config not available)" ;
else
2017-05-31 12:51:26 +00:00
resultStr = ihead . ConfigStruct . ToString ( 1 ) ;
2016-02-16 14:57:30 +00:00
}
#endif
2015-08-11 06:50:32 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-11 06:50:32 +00:00
}
2015-08-15 15:51:54 +00:00
2015-08-14 12:33:36 +00:00
/// <summary>
/// Read a complete calibration structure from the watermeter
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr ReadCalibration ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-14 12:33:36 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2015-08-14 12:33:36 +00:00
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2015-08-14 12:33:36 +00:00
2015-08-17 14:02:30 +00:00
CommErr error = CommErr . Read ;
2015-08-14 12:33:36 +00:00
2015-08-15 15:51:54 +00:00
/// Read calibration
byte [ ] calib = null ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-14 12:33:36 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Calibration , 0 , CalibrationStruct . Length , out calib , cfg . CommTimeout ) )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
ihead . CalibrationStruct = CalibrationStruct . FromByteArray ( calib ) ;
#if IPERL
2017-07-18 06:33:20 +00:00
if ( wm ! = null & & wm . OrigCalibFactor = = 0 )
2017-06-15 11:08:31 +00:00
{
2017-07-18 06:33:20 +00:00
wm . OrigCalibFactor = ihead . CalibrationStruct . Calibration ;
2017-06-15 11:08:31 +00:00
wm . FWVersion = ihead . CalibrationStruct . FWVersionStr ( ) ;
}
2017-05-31 12:51:26 +00:00
#endif
2017-06-15 11:08:31 +00:00
resultStr = ihead . CalibrationStruct . ToString ( ) ;
2017-05-31 12:51:26 +00:00
error = ihead . VerifyIPerlType ( ) ? CommErr . None : CommErr . WrongIPerlType ;
2015-08-15 15:51:54 +00:00
break ;
}
2015-08-14 12:33:36 +00:00
}
2015-08-15 15:51:54 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-14 12:33:36 +00:00
}
2015-08-15 15:51:54 +00:00
2015-08-14 12:33:36 +00:00
/// <summary>
/// Write the calculated calibration factor to the water meter.
/// Read a part of CalibrationStruct afterwards to verify factor was written correctly.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr WriteCalibrationFactor ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-11 06:50:32 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2015-08-15 15:51:54 +00:00
2016-11-10 13:07:11 +00:00
///
2015-10-16 09:24:03 +00:00
/// Parse calibration factor (1 argument) or calibration factor limits (2 arguments)
2016-11-10 13:07:11 +00:00
///
2015-10-16 09:24:03 +00:00
UInt16 newCalibFactor = 0 ;
2015-09-04 11:49:04 +00:00
if ( multiTestParams [ currentActivityStep ] . Activity . Length > WriteCalibrationFactorStr . Length )
2015-10-16 09:24:03 +00:00
{
UInt16 factorLimitLo ;
UInt16 factorLimitHi ;
UInt16 val ;
2015-09-04 11:49:04 +00:00
string calibFactrorStr = multiTestParams [ currentActivityStep ] . Activity . Substring ( WriteCalibrationFactorStr . Length + 1 ) ;
2015-10-16 09:24:03 +00:00
string [ ] arguments = calibFactrorStr . Split ( new char [ ] { ' ' } ) ;
if ( arguments . Length > = 2 & &
UInt16 . TryParse ( arguments [ 0 ] , out factorLimitLo ) & & factorLimitLo > 0 & &
UInt16 . TryParse ( arguments [ 1 ] , out factorLimitHi ) & & factorLimitHi > 0 )
{
2017-07-14 14:31:35 +00:00
if ( ihead . LastTestResult = = null | | ! ihead . LastTestResult . TestDone ) return CommErr . MissingTest ;
2017-07-18 06:33:20 +00:00
newCalibFactor = ihead . CalculateNewCalibFactor ( ihead . LastTestResult , ihead . CalibFactor , factorLimitLo , factorLimitHi ) ;
2015-10-16 09:24:03 +00:00
}
else if ( arguments . Length = = 1 & & UInt16 . TryParse ( arguments [ 0 ] , out val ) & & val > 0 )
{
newCalibFactor = val ; /// Update with specified value
}
2017-07-14 14:31:35 +00:00
else if ( arguments . Length = = 1 & & wm . GetTestData ( arguments [ 0 ] ) ! = null )
{
/// Get test data is test name
Results . Entities . TestData adjustTestData = wm . GetTestData ( arguments [ 0 ] ) ;
Results . Entities . MeterTestRslt adjustTestRslt ;
if ( adjustTestData = = null )
{
return CommErr . MissingTest ;
}
else if ( adjustTestData . Repeats = = 1 )
{
/// Find a test result if Repeats == 1
adjustTestRslt = wm . GetMeterTestRslt ( arguments [ 0 ] ) ;
if ( adjustTestRslt = = null | | ! adjustTestRslt . TestDone ) return CommErr . MissingTest ;
}
else
{
/// Calculate a summarized test result if Repeats > 1
adjustTestRslt = new Results . Entities . MeterTestRslt ( ) ;
for ( int i = 1 ; i < = adjustTestData . Repeats ; i + + )
{
Results . Entities . MeterTestRslt oneMTR = wm . GetMeterTestRslt ( Utils . TestTitle ( adjustTestData , i ) ) ;
if ( oneMTR = = null | | ! oneMTR . TestDone ) return CommErr . MissingTest ;
adjustTestRslt . VolumeMeter + = oneMTR . VolumeMeter ;
adjustTestRslt . VolumeRef + = oneMTR . VolumeRef ;
}
}
2017-07-18 06:33:20 +00:00
newCalibFactor = ihead . CalculateNewCalibFactor ( adjustTestRslt , ihead . CalibFactor , ihead . FactorLimitLo , ihead . FactorLimitHi ) ;
2017-07-14 14:31:35 +00:00
}
else
2015-10-16 09:24:03 +00:00
{
2017-07-14 14:31:35 +00:00
if ( ihead . LastTestResult = = null | | ! ihead . LastTestResult . TestDone ) return CommErr . MissingTest ;
2017-07-18 06:33:20 +00:00
newCalibFactor = ihead . CalculateNewCalibFactor ( ihead . LastTestResult , ihead . CalibFactor , ihead . FactorLimitLo , ihead . FactorLimitHi ) ;
2015-10-16 09:24:03 +00:00
}
}
else
{
2017-07-14 14:31:35 +00:00
if ( ihead . LastTestResult = = null | | ! ihead . LastTestResult . TestDone ) return CommErr . MissingTest ;
2017-07-18 06:33:20 +00:00
newCalibFactor = ihead . CalculateNewCalibFactor ( ihead . LastTestResult , ihead . CalibFactor , ihead . FactorLimitLo , ihead . FactorLimitHi ) ;
2015-10-16 09:24:03 +00:00
}
2017-06-07 14:22:18 +00:00
if ( newCalibFactor = = 0 ) return CommErr . CalibFactorOoRange ;
2016-11-10 13:07:11 +00:00
///
/// Start communication with iPerl
///
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2017-06-07 14:22:18 +00:00
2016-11-10 13:07:11 +00:00
CommErr error ;
2015-08-19 19:12:10 +00:00
byte [ ] data = new byte [ 2 ] { ( byte ) ( newCalibFactor & 0x00FF ) , ( byte ) ( ( newCalibFactor > > 8 ) & 0x00FF ) } ;
2016-11-10 13:07:11 +00:00
int writeAndVerifyRetries = 0 ;
do
2015-08-15 15:51:54 +00:00
{
2016-11-10 13:07:11 +00:00
///
/// Write the new calibration factor (up to cfg.MaxCommRetries tims)
///
error = CommErr . Write ;
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Calibration , 2 , 2 , data , cfg . CommTimeout ) )
2015-08-24 13:16:14 +00:00
{
2016-11-10 13:07:11 +00:00
///
/// Read and verify the calibration factor
///
error = CommErr . ReadAfterWrite ;
byte [ ] calib_2_3 = null ;
2017-05-31 12:51:26 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Calibration , 2 , 2 , out calib_2_3 , cfg . CommTimeout ) )
2015-08-15 15:51:54 +00:00
{
2016-11-10 13:07:11 +00:00
error = CommErr . Verify ;
if ( calib_2_3 ! = null & & calib_2_3 . Length = = 2 & & data [ 0 ] = = calib_2_3 [ 0 ] & & data [ 1 ] = = calib_2_3 [ 1 ] )
{
error = CommErr . None ;
2017-05-31 12:51:26 +00:00
ihead . CalibrationStruct . Update ( data , 2 ) ;
#if IPERL
if ( wm ! = null ) wm . CalibFactor = newCalibFactor ;
#endif
resultStr = ihead . CalibrationStruct . ToString ( ) ;
2016-11-10 13:07:11 +00:00
break ;
}
2015-08-15 15:51:54 +00:00
}
2015-08-14 09:38:53 +00:00
}
2016-11-10 13:07:11 +00:00
2017-05-31 12:51:26 +00:00
ihead . CalibrationStruct . Update ( data , 2 ) ;
2015-08-15 15:51:54 +00:00
}
2016-11-10 13:07:11 +00:00
while ( + + writeAndVerifyRetries < = cfg . MaxCommRetries ) ;
2015-08-11 06:50:32 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-14 09:38:53 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-15 15:51:54 +00:00
}
2015-08-11 06:50:32 +00:00
2016-11-02 12:16:07 +00:00
/// <summary>
/// Normalize calibration factor in case ti is close to value 8000.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2016-11-02 12:16:07 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr NormalizeCalibrationFactor ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2016-11-02 12:16:07 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2016-11-02 12:16:07 +00:00
2017-07-18 06:33:20 +00:00
if ( ihead . CalibFactor < = 5000 )
2016-11-02 12:16:07 +00:00
{
resultStr = "Calibratin factor is OK" ;
return CommErr . None ; /// No need to update the calibration factor
}
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2016-11-02 12:16:07 +00:00
CommErr error = CommErr . Write ;
/// Determine the new calibration factor
UInt16 newCalibFactor = 0 ;
2017-05-31 12:51:26 +00:00
switch ( ihead . CalibrationStruct . MeterType )
2016-11-02 12:16:07 +00:00
{
case MeterType . DN15 : newCalibFactor = 2650 ; break ;
case MeterType . DN20 : newCalibFactor = 3746 ; break ;
case MeterType . DN25 : newCalibFactor = 3300 ; break ;
case MeterType . DN32 : newCalibFactor = 2500 ; break ;
case MeterType . DN40 : newCalibFactor = 3000 ; break ;
case MeterType . DN26 :
case MeterType . CoaxManifold :
default :
newCalibFactor = 3040 ;
break ;
}
byte [ ] data = new byte [ 2 ] { ( byte ) ( newCalibFactor & 0x00FF ) , ( byte ) ( ( newCalibFactor > > 8 ) & 0x00FF ) } ;
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . Calibration , 2 , 2 , data , cfg . CommTimeout ) )
2016-11-02 12:16:07 +00:00
{
error = CommErr . None ;
2017-05-31 12:51:26 +00:00
ihead . CalibrationStruct . Update ( data , 2 ) ;
2016-11-02 12:16:07 +00:00
break ;
}
}
if ( error = = CommErr . None )
{
error = CommErr . Verify ;
/// Read calibration
byte [ ] calib_2_3 = null ;
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-05-31 12:51:26 +00:00
if ( 0 = = ReadRequestPort ( ihead , MessageID . Calibration , 2 , 2 , out calib_2_3 , cfg . CommTimeout ) )
2016-11-02 12:16:07 +00:00
{
error = CommErr . None ;
2017-05-31 12:51:26 +00:00
ihead . CalibrationStruct . Update ( calib_2_3 , 2 ) ;
resultStr = ihead . CalibrationStruct . ToString ( ) ;
2016-11-02 12:16:07 +00:00
break ;
}
}
}
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2016-11-02 12:16:07 +00:00
return error ;
}
2016-02-14 18:02:07 +00:00
const int Hz2CorrFactorsAddr = 0x1875 ; /// Used by Reset2HzCorrection(...) and Write2HzCorrection(...)
2015-08-15 15:51:54 +00:00
const int Q2CorrFactorsAddr = 0x1878 ; /// Used by ResetQ2Correction(...) and WriteQ2Correction(...)
2015-08-11 06:50:32 +00:00
2015-08-15 15:51:54 +00:00
/// <summary>
/// Reset both Q2 correction factors in the memory to 0.
/// Read them back to verify factors were written correctly.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr ResetQ2Correction ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2015-08-14 12:33:36 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2015-08-15 15:51:54 +00:00
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
CommErr error = CommErr . Write ;
2015-08-15 15:51:54 +00:00
/// Write zero Q2 correction
2015-08-22 11:58:55 +00:00
byte [ ] wrData = new byte [ 2 ] { 0 , 0 } ;
///
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . MetrologyMemory , Q2CorrFactorsAddr , wrData . Length , wrData , cfg . CommTimeout ) )
2016-02-16 13:44:10 +00:00
{
error = CommErr . None ;
break ;
}
2015-08-15 15:51:54 +00:00
}
2016-02-16 13:44:10 +00:00
///
/// Verification disabled on 16.02.2016
2016-10-27 12:27:37 +00:00
///
#if VERIFY_Q2_CORR_RESET
2015-08-22 11:58:55 +00:00
/// Verify the correction factors
2015-08-17 14:02:30 +00:00
if ( error = = CommErr . None )
2015-08-15 15:51:54 +00:00
{
2015-08-17 14:02:30 +00:00
error = CommErr . Verify ;
2015-08-15 15:51:54 +00:00
/// Read calibration
byte [ ] rdData = null ;
2015-09-06 21:36:14 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
2015-08-15 15:51:54 +00:00
{
2017-07-14 14:31:35 +00:00
if ( ( 0 = = ReadRequestPort ( ihead , MessageID . MetrologyMemory , Q2CorrFactorsAddr , 2 , out rdData , cfg . CommTimeout ) ) & &
2015-08-15 15:51:54 +00:00
( rdData ! = null ) & & ( rdData . Length = = 2 ) & & ( rdData [ 0 ] = = 0 ) & & ( rdData [ 1 ] = = 0 ) )
{
2015-08-17 14:02:30 +00:00
error = CommErr . None ;
2015-08-15 15:51:54 +00:00
resultStr = "Q2 correction factors reset to 0" ;
2017-07-14 14:31:35 +00:00
ihead . Q2CorrectionFactor = 0 ;
2016-02-16 13:44:10 +00:00
break ;
}
}
}
#else
if ( error = = CommErr . None )
{
resultStr = "Q2 corrections reset to 0" ;
2017-05-31 12:51:26 +00:00
ihead . Q2CorrRFlow = 0 ;
2016-02-16 13:44:10 +00:00
}
#endif
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2016-02-16 13:44:10 +00:00
return error ;
}
/// <summary>
/// Reset 2Hz correction factor in the memory to 0.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2016-02-16 13:44:10 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr Reset2HzCorrection ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2016-02-16 13:44:10 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2016-02-16 13:44:10 +00:00
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2016-02-16 13:44:10 +00:00
CommErr error = CommErr . Write ;
/// Write zero Q2 correction
byte [ ] wrData = new byte [ 1 ] { 0 } ;
///
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . MetrologyMemory , Hz2CorrFactorsAddr , wrData . Length , wrData , cfg . CommTimeout ) )
2016-02-16 13:44:10 +00:00
{
error = CommErr . None ;
break ;
}
}
///
/// Verification disabled on 16.02.2016
///
#if false
/// Verify the correction factors
if ( error = = CommErr . None )
{
error = CommErr . Verify ;
/// Read calibration
byte [ ] rdData = null ;
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-07-14 14:31:35 +00:00
if ( ( 0 = = ReadRequestPort ( ihead , MessageID . MetrologyMemory , Hz2CorrFactorsAddr , 1 , out rdData , cfg . CommTimeout ) ) & &
2016-02-16 13:44:10 +00:00
( rdData ! = null ) & & ( rdData . Length = = 2 ) & & ( rdData [ 0 ] = = 0 ) & & ( rdData [ 1 ] = = 0 ) )
{
error = CommErr . None ;
resultStr = "2Hz correction reset to 0" ;
2017-07-14 14:31:35 +00:00
ihead . Q2CorrectionFactor = 0 ;
2015-08-15 15:51:54 +00:00
break ;
}
}
}
2016-02-16 13:44:10 +00:00
#else
if ( error = = CommErr . None )
{
resultStr = "2Hz correction reset to 0" ;
2017-07-18 06:33:20 +00:00
ihead . Hz2Correction = 0 ;
2016-02-16 13:44:10 +00:00
}
#endif
2015-08-14 12:33:36 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2015-08-15 15:51:54 +00:00
2015-08-17 14:02:30 +00:00
return error ;
2015-08-15 15:51:54 +00:00
}
/// <summary>
/// Write the calculated Q2 correction factors to the memory.
/// Read them back to verify factors were written correctly.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2015-08-15 15:51:54 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-14 14:31:35 +00:00
static CommErr WriteQ2Correction ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr , Q2CorrType q2CorrType , string q2TestName , bool updateQ2adjByCalibFactor )
2015-08-14 12:33:36 +00:00
{
2017-07-14 14:31:35 +00:00
//if (ihead == null || ihead.CommFailed) return CommErr.CommFailed;
Results . Entities . MeterTestRslt q2adjResult ;
Results . Entities . TestData q2adjTestData ;
///
if ( string . IsNullOrEmpty ( q2TestName ) )
{
/// Use ihead.LastTestResult is no test name is specified as an argument
q2adjResult = ihead . LastTestResult ;
q2adjTestData = q2adjResult . TestRslt . TestData ;
if ( q2adjResult = = null | | ! q2adjResult . TestDone ) return CommErr . MissingTest ;
}
else
{
/// Get test data is test name
q2adjTestData = wm . GetTestData ( q2TestName ) ;
if ( q2adjTestData = = null )
{
return CommErr . MissingTest ;
}
else if ( q2adjTestData . Repeats = = 1 )
{
/// Find a test result if Repets == 1
q2adjResult = wm . GetMeterTestRslt ( q2TestName ) ;
if ( q2adjResult = = null | | ! q2adjResult . TestDone ) return CommErr . MissingTest ;
}
else
{
/// Calculate a summarized test result if Repeats > 1
q2adjResult = new Results . Entities . MeterTestRslt ( ) ;
for ( int i = 1 ; i < = q2adjTestData . Repeats ; i + + )
{
Results . Entities . MeterTestRslt oneMTR = wm . GetMeterTestRslt ( string . Format ( "{0} ({1}/{2})" , q2TestName , i , q2adjTestData . Repeats ) ) ;
if ( oneMTR = = null | | ! oneMTR . TestDone ) return CommErr . MissingTest ;
2015-08-15 15:51:54 +00:00
2017-07-14 14:31:35 +00:00
q2adjResult . VolumeMeter + = oneMTR . VolumeMeter ;
q2adjResult . VolumeRef + = oneMTR . VolumeRef ;
}
#if IPERL
if ( updateQ2adjByCalibFactor )
{
if ( wm . OrigCalibFactor = = 0 ) return CommErr . CalibFactorOoRange ;
q2adjResult . VolumeMeter * = ( ( double ) wm . CalibFactor / ( double ) wm . OrigCalibFactor ) ;
}
#endif
q2adjResult . Error = Formulas . ErrorFromVolumes ( q2adjResult . VolumeMeter , q2adjResult . VolumeRef ) ;
}
}
///
if ( q2adjResult = = null ) return CommErr . CommFailed ; /// This should never happen
2017-07-18 06:33:20 +00:00
ihead . Q2ErrWOCorrection = q2adjResult . Error ;
2017-05-31 12:51:26 +00:00
ihead . Q2CorrectionDone = false ;
ihead . Q2CorrRFlow = 0 ;
2016-02-16 13:44:10 +00:00
2017-03-31 12:17:18 +00:00
double q2Correction = 0 ;
Byte q2CorrRFlow = 0 ;
Byte q2CorrLFlow = 0 ;
2015-08-14 12:33:36 +00:00
2017-07-14 14:31:35 +00:00
if ( q2CorrType = = Q2CorrType . Standard )
2017-03-31 12:17:18 +00:00
{
///
/// Standard process
///
2017-07-18 06:33:20 +00:00
if ( Math . Abs ( ihead . Q2ErrWOCorrection ) < = 0.5 )
2017-03-31 12:17:18 +00:00
{
resultStr = string . Format ( "Q2 correction = 0 (writing bypassed)" ) ;
return CommErr . None ;
}
2015-08-11 06:50:32 +00:00
2017-07-14 14:31:35 +00:00
if ( ! ihead . CalculateQ2CorrectionFactor ( q2adjResult , q2adjTestData , out q2Correction ) )
2017-03-31 12:17:18 +00:00
{
return CommErr . None ; /// Q2 error is too large, water meter failed anyhow
}
2017-03-19 21:03:31 +00:00
2017-03-31 12:17:18 +00:00
q2CorrRFlow = ( byte ) ( ( int ) Math . Round ( 0.5 * q2Correction ) & 0x000000FF ) ;
q2CorrLFlow = ( byte ) ( ( int ) Math . Round ( q2Correction ) & 0x000000FF ) ;
}
2017-07-14 14:31:35 +00:00
else if ( q2CorrType = = Q2CorrType . Dewa )
2017-03-31 12:17:18 +00:00
{
///
2017-07-14 14:31:35 +00:00
/// Process for DEWA
2017-03-31 12:17:18 +00:00
///
2017-07-18 06:33:20 +00:00
if ( ihead . Q2ErrWOCorrection > = 0 & & ihead . Q2ErrWOCorrection < = 1.0 )
2017-03-31 12:17:18 +00:00
{
resultStr = string . Format ( "Q2 correction = 0 (writing bypassed)" ) ;
return CommErr . None ;
}
2017-03-19 21:03:31 +00:00
2017-07-14 14:31:35 +00:00
if ( ! ihead . CalculateQ2CorrectionFactor ( q2adjResult , q2adjTestData , out q2Correction ) )
2017-03-31 12:17:18 +00:00
{
return CommErr . None ; /// Q2 error is too large, water meter failed anyhow
}
2017-03-19 21:03:31 +00:00
2017-07-18 06:33:20 +00:00
if ( ihead . Q2ErrWOCorrection < 0 )
2017-03-31 12:17:18 +00:00
{
q2CorrRFlow = ( byte ) ( ( int ) Math . Round ( 1.1 * q2Correction ) & 0x000000FF ) ;
q2CorrLFlow = ( byte ) ( ( int ) Math . Round ( 1.1 * q2Correction ) & 0x000000FF ) ;
}
2017-07-14 14:31:35 +00:00
else /// if (wm.Q2ErrorWOCorrection > 1.0)
2017-03-31 12:17:18 +00:00
{
q2CorrRFlow = ( byte ) ( ( int ) Math . Round ( 0.5 * q2Correction ) & 0x000000FF ) ;
q2CorrLFlow = ( byte ) ( ( int ) Math . Round ( 0.5 * q2Correction ) & 0x000000FF ) ;
}
}
2017-07-14 14:31:35 +00:00
else if ( q2CorrType = = Q2CorrType . Greece )
{
///
/// Process for Greece
///
if ( ! ihead . CalculateQ2CorrectionFactor ( q2adjResult , q2adjTestData , out q2Correction ) )
{
return CommErr . None ; /// Q2 error is too large, water meter failed anyhow
}
q2CorrRFlow = ( byte ) ( ( int ) Math . Round ( q2Correction ) & 0x000000FF ) ;
q2CorrLFlow = ( byte ) ( ( int ) Math . Round ( q2Correction ) & 0x000000FF ) ;
}
2017-03-19 21:03:31 +00:00
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2017-03-19 21:03:31 +00:00
CommErr error = CommErr . Write ;
2017-03-31 12:17:18 +00:00
byte [ ] wrData = new byte [ 2 ] { q2CorrRFlow , q2CorrLFlow } ;
///
2017-03-19 21:03:31 +00:00
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . MetrologyMemory , Q2CorrFactorsAddr , wrData . Length , wrData , cfg . CommTimeout ) )
2017-03-19 21:03:31 +00:00
{
error = CommErr . None ;
break ;
}
}
///
/// Verification disabled on 16.02.2016
///
#if false
if ( error = = CommErr . None )
{
error = CommErr . Verify ;
/// Read calibration
byte [ ] rdData = null ;
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-07-14 14:31:35 +00:00
if ( ( 0 = = ReadRequestPort ( ihead , MessageID . MetrologyMemory , Q2CorrFactorsAddr , 2 , out rdData , cfg . CommTimeout ) ) & &
2017-03-19 21:03:31 +00:00
( rdData ! = null ) & & ( rdData . Length = = 2 ) & & ( rdData [ 0 ] = = q2CorrRFlow ) & & ( rdData [ 1 ] = = q2CorrLFlow ) )
{
error = CommErr . None ;
resultStr = string . Format ( "Q2 factors: R-flow={0}, L-flow={1}" , ( SByte ) q2CorrRFlow , ( SByte ) q2CorrLFlow ) ;
2017-05-31 12:51:26 +00:00
rfidDataLogger . Warn ( ihead . Name + ": " + resultStr ) ;
ihead . Q2CorrectionDone = true ;
ihead . Q2Correction = q2Correction ;
ihead . Q2CorrRFlow = ( int ) ( sbyte ) q2CorrRFlow ;
ihead . Q2CorrLFlow = ( int ) ( sbyte ) q2CorrLFlow ;
#if IPERL
if ( wm ! = null )
{
2017-07-14 14:31:35 +00:00
wm . Q2ErrWOCorrection = ihead . Q2ErrorWOCorrection ;
2017-05-31 12:51:26 +00:00
wm . Q2CorrectionDone = ihead . Q2CorrectionDone ;
wm . Q2Correction = ihead . Q2Correction ;
wm . Q2CorrRFlow = ihead . Q2CorrRFlow ;
wm . Q2CorrLFlow = ihead . Q2CorrLFlow ;
}
#endif
2017-03-19 21:03:31 +00:00
break ;
}
}
}
#else
if ( error = = CommErr . None )
{
resultStr = string . Format ( "Q2 correction: R-flow={0}, L-flow={1}" , ( SByte ) q2CorrRFlow , ( SByte ) q2CorrLFlow ) ;
2017-05-31 12:51:26 +00:00
rfidDataLogger . Warn ( ihead . Name + ": " + resultStr ) ;
ihead . Q2CorrectionDone = true ;
ihead . Q2Correction = q2Correction ;
ihead . Q2CorrRFlow = ( int ) ( sbyte ) q2CorrRFlow ;
ihead . Q2CorrLFlow = ( int ) ( sbyte ) q2CorrLFlow ;
#if IPERL
if ( wm ! = null )
{
2017-07-18 06:33:20 +00:00
wm . Q2ErrWOCorrection = ihead . Q2ErrWOCorrection ;
2017-05-31 12:51:26 +00:00
wm . Q2CorrectionDone = ihead . Q2CorrectionDone ;
wm . Q2Correction = ihead . Q2Correction ;
wm . Q2CorrRFlow = ihead . Q2CorrRFlow ;
wm . Q2CorrLFlow = ihead . Q2CorrLFlow ;
}
#endif
2017-03-31 12:17:18 +00:00
}
2017-03-19 21:03:31 +00:00
#endif
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2017-03-19 21:03:31 +00:00
return error ;
}
2016-02-15 14:16:44 +00:00
/// <summary>
/// Write the calculated 2Hz correction factor to the memory.
/// </summary>
2017-05-31 12:51:26 +00:00
/// <param name="ihead">Water meter object</param>
2016-02-15 14:16:44 +00:00
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
2017-07-18 06:33:20 +00:00
static CommErr Write2HzCorrection ( IperlHead ihead , Results . Entities . WaterMeter wm , ref string resultStr )
2016-02-15 14:16:44 +00:00
{
2017-05-31 12:51:26 +00:00
if ( ihead . CommFailed ) return CommErr . CommFailed ;
2016-02-15 14:16:44 +00:00
2016-02-16 13:44:10 +00:00
/// Calculate the correction
2017-05-31 12:51:26 +00:00
ihead . Hz2CorrectionDone = false ;
2016-02-16 13:44:10 +00:00
int hz2CorrectionFactor ;
2017-05-31 12:51:26 +00:00
bool wmOK = ihead . Calculate2HzCorrectionFactor ( ihead . LastTestResult2 , ihead . LastTestResult , out ihead . Diff2Hz8Hz , out hz2CorrectionFactor ) ;
2016-02-16 13:44:10 +00:00
2016-02-15 14:16:44 +00:00
if ( hz2CorrectionFactor = = 0 )
{
2016-02-16 13:44:10 +00:00
resultStr = string . Format ( "2Hz correction = 0 (writing bypassed)" ) ;
2016-02-15 14:16:44 +00:00
return CommErr . None ;
}
2017-05-31 12:51:26 +00:00
if ( OpenPort ( ihead ) ! = 0 ) return CommErr . OpenPort ; /// Open RFID port
2016-02-15 14:16:44 +00:00
CommErr error = CommErr . Write ;
2016-02-16 13:44:10 +00:00
Byte hz2CorrectionByte = ( byte ) ( hz2CorrectionFactor & 0x000000FF ) ;
2016-02-15 14:16:44 +00:00
byte [ ] wrData = new byte [ 1 ] { hz2CorrectionByte } ;
///
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
2017-05-31 12:51:26 +00:00
if ( 0 = = WriteRequestPort ( ihead , MessageID . MetrologyMemory , Hz2CorrFactorsAddr , wrData . Length , wrData , cfg . CommTimeout ) )
2016-02-16 13:44:10 +00:00
{
error = CommErr . None ;
2017-07-18 06:33:20 +00:00
ihead . Hz2Correction = hz2CorrectionFactor ;
2017-05-31 12:51:26 +00:00
ihead . Hz2CorrectionDone = true ;
#if IPERL
if ( wm ! = null )
{
wm . Hz2CorrectionDone = ihead . Hz2CorrectionDone ;
2017-07-18 06:33:20 +00:00
wm . Hz2Correction = ihead . Hz2Correction ;
2017-05-31 12:51:26 +00:00
}
#endif
2016-02-16 13:44:10 +00:00
break ;
}
2016-02-15 14:16:44 +00:00
}
2016-02-16 13:44:10 +00:00
///
/// Verification disabled on 16.02.2016
///
#if false
2016-02-15 14:16:44 +00:00
if ( error = = CommErr . None )
{
error = CommErr . Verify ;
/// Read calibration
byte [ ] rdData = null ;
for ( int j = 0 ; j < cfg . MaxCommRetries ; j + + )
{
if ( ( 0 = = ReadRequestPort ( wm , MessageID . MetrologyMemory , Hz2CorrFactorsAddr , 1 , out rdData , cfg . CommTimeout ) ) & &
( rdData ! = null ) & & ( rdData . Length = = 2 ) & & ( rdData [ 0 ] = = hz2CorrectionByte ) )
{
error = CommErr . None ;
resultStr = string . Format ( "2Hz factor = {0}" , ( SByte ) hz2CorrectionByte ) ;
2017-07-14 14:31:35 +00:00
rfidDataLogger . Warn ( ihead . Name + ": " + resultStr ) ;
ihead . Hz2CorrectionFactor = hz2CorrectionFactor ;
#if IPERL
if ( wm ! = null )
{
wm . Diff2Hz8Hz = ihead . Diff2Hz8Hz ;
wm . Hz2CorrectionDone = ihead . Hz2CorrectionDone ;
wm . Hz2Correction = ihead . Hz2CorrectionFactor ;
}
#endif
2016-02-15 14:16:44 +00:00
break ;
}
}
}
2016-02-16 13:44:10 +00:00
#else
if ( error = = CommErr . None )
{
resultStr = string . Format ( "2Hz correction = {0}" , ( SByte ) hz2CorrectionByte ) ;
2017-05-31 12:51:26 +00:00
rfidDataLogger . Warn ( ihead . Name + ": " + resultStr ) ;
ihead . Hz2CorrectionDone = true ;
2017-07-18 06:33:20 +00:00
ihead . Hz2Correction = hz2CorrectionFactor ;
2017-07-14 14:31:35 +00:00
#if IPERL
if ( wm ! = null )
{
wm . Diff2Hz8Hz = ihead . Diff2Hz8Hz ;
wm . Hz2CorrectionDone = ihead . Hz2CorrectionDone ;
2017-07-18 06:33:20 +00:00
wm . Hz2Correction = ihead . Hz2Correction ;
2017-07-14 14:31:35 +00:00
}
#endif
2016-02-16 13:44:10 +00:00
}
#endif
2016-02-15 14:16:44 +00:00
2017-05-31 12:51:26 +00:00
ClosePort ( ihead ) ; /// Close RFID port
2016-02-15 14:16:44 +00:00
return error ;
}
2015-08-11 06:50:32 +00:00
/// <summary>
/// Called when communication with one watermeter is completed
/// </summary>
public static void OnCommCompleted ( object sender , CommCompletedEventArgs data )
{
if ( CommCompletedHandler = = null ) return ;
try { CommCompletedHandler ( sender , data ) ; }
catch ( Exception e ) { log . Error ( "CommCompletedHandler(...) failed" , e ) ; }
}
public static event EventHandler < CommCompletedEventArgs > CommCompletedHandler ;
void DoOnCommCompleted ( object sender , CommCompletedEventArgs data )
{
2015-09-05 22:09:52 +00:00
if ( data . WMNr > = 0 ) messages [ data . WMNr ] . Text = data . CommMessage ;
2015-08-12 14:05:06 +00:00
2017-05-31 12:51:26 +00:00
for ( int i = 0 ; i < iperlHeads . Count ; i + + )
2015-09-21 14:29:12 +00:00
{
2017-05-31 12:51:26 +00:00
counters [ i ] . BackColor = ( iperlHeads [ i ] . FlushedDataDelta = = 0 ) ? Color . Red : Color . Green ;
2015-09-21 14:29:12 +00:00
}
2015-08-12 14:05:06 +00:00
lock ( this )
{
2015-08-13 06:35:34 +00:00
if ( + + completedCommCount < rfidPortNrs . Count ) return ;
2015-08-12 14:05:06 +00:00
completedCommCount = 0 ;
}
2015-08-11 06:50:32 +00:00
if ( currentGroup < lastGroup )
{
2015-08-12 14:05:06 +00:00
/// Go to the next step / next group
2015-09-04 11:49:04 +00:00
if ( quido ! = null )
2015-08-11 06:50:32 +00:00
{
2015-09-05 22:09:52 +00:00
quido . SetOutputs ( ( ushort ) ( 16 - currentGroup - 1 ) ) ;
2015-08-12 14:05:06 +00:00
Thread . Sleep ( 100 ) ;
2015-08-11 06:50:32 +00:00
}
2015-09-05 22:09:52 +00:00
currentGroup + + ;
}
2015-09-04 11:49:04 +00:00
else if ( currentActivityStep + 1 < multiTestParams . Count )
{
2015-09-05 22:09:52 +00:00
currentGroup = 0 ;
2015-09-04 11:49:04 +00:00
currentActivityStep + + ;
activityLabel . Text = multiTestParams [ currentActivityStep ] . Activity ;
if ( quido ! = null )
{
2015-09-05 22:09:52 +00:00
quido . SetOutputs ( ( ushort ) ( 16 - currentGroup - 1 ) ) ;
2015-09-04 11:49:04 +00:00
Thread . Sleep ( 100 ) ;
}
2015-09-05 22:09:52 +00:00
currentGroup + + ;
2015-09-04 11:49:04 +00:00
}
else
2015-08-11 06:50:32 +00:00
{
2015-08-12 14:05:06 +00:00
/// Wait until all threads are finished
2015-08-11 06:50:32 +00:00
workerThreads [ data . ThreadId ] . Join ( 2000 ) ;
NormalClose ( ) ;
}
}
/// <summary>
/// Called when communication with all watermeters is completed
/// </summary>
public static void OnAllCompleted ( object sender , AllCompletedEventArgs data )
{
if ( AllCompletedHandler = = null ) return ;
try { AllCompletedHandler ( sender , data ) ; }
catch ( Exception e ) { log . Error ( "AllCompletedHandler(...) failed" , e ) ; }
}
public static event EventHandler < AllCompletedEventArgs > AllCompletedHandler ;
void DoOnAllCompleted ( object sender , AllCompletedEventArgs data )
{
Text = data . CommMessage ;
}
2015-09-11 17:36:37 +00:00
/// <summary>
2016-01-03 01:05:35 +00:00
/// Update test result representing RFID communication success/failure
2015-09-11 17:36:37 +00:00
/// </summary>
/// <param name="test"></param>
2016-01-19 16:38:09 +00:00
void UpdateRfidCommResult ( IList < Config . Entities . Test > tests )
2015-09-11 17:36:37 +00:00
{
2016-01-08 18:18:45 +00:00
DateTime endTime = DateTime . Now ;
int testTime = StateMachine . Time - startTimeSec ;
2015-09-11 17:36:37 +00:00
2016-01-19 16:38:09 +00:00
if ( ! tests . Contains ( StateMachine . Tests [ 0 ] ) )
2016-01-03 01:05:35 +00:00
{
2016-01-19 16:38:09 +00:00
tests . Insert ( 0 , StateMachine . Tests [ 0 ] ) ; /// Add RFID test as the 1st item
2016-01-08 18:18:45 +00:00
}
2016-01-03 01:05:35 +00:00
2016-01-19 16:38:09 +00:00
foreach ( var test in tests )
2016-01-08 18:18:45 +00:00
{
2016-01-19 16:38:09 +00:00
Results . Entities . TestRslt tstRslt = ProcessData . BatchRslts . GetTestRslt ( test . Name , test . Part ) ;
2016-01-08 18:18:45 +00:00
if ( tstRslt ! = null )
{
/// Auxiliary results ... not required
/// Main results
tstRslt . StartTime = tstRslt . Batch . StartTime ;
tstRslt . EndTime = endTime ;
tstRslt . FlowSetTime = 0 ;
tstRslt . TestTime + = testTime ; /// [s] total communication time of all tests
2017-05-31 12:51:26 +00:00
for ( int i = 0 ; i < iperlHeads . Count ; i + + )
{
Results . Entities . MeterTestRslt meterRslt =
ProcessData . BatchRslts . GetMeterTestRslt ( test . Name , waterMeterPositions [ i ] , Config . Entities . CompoundMeterId . Single ) ;
2016-01-08 18:18:45 +00:00
2017-05-31 12:51:26 +00:00
if ( meterRslt ! = null & & iperlHeads [ i ] ! = null )
{
meterRslt . WaterMeter . SerialNr = iperlHeads [ i ] . SerialNr ;
meterRslt . Passed = ( ! iperlHeads [ i ] . CommFailed & & ! iperlHeads [ i ] . Disabled ) ;
meterRslt . TestDone = true ;
}
}
2016-01-08 18:18:45 +00:00
}
2016-01-03 01:05:35 +00:00
}
2015-09-11 17:36:37 +00:00
}
2015-08-11 06:50:32 +00:00
}
}