/// /// Copyright (c) 2015-2021 Sensus Slovensko a.s. /// //#define VERIFY_ACTIVE_MODE //#define VERIFY_Q2_CORR_RESET using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Windows.Forms; using log4net; using Common; using Config; using Config.Entities; using TBF.Resources; using TBF.Rig.Sequences; using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead; namespace TBF.Rig.TestMethods.iPerlCommunication { public enum CommErr { None = 0, CommFailed, /// 1 OpenPort, /// 2 Read, /// 3 Read1, /// 4 Read2, /// 5 Read3, /// 6 Read4, /// 7 Write, /// 8 ReadAfterWrite, /// 9 CmdActive, /// 0AH = 10 CmdTest, /// 0BH = 11 Verify, /// 0CH = 12 WrongIPerlType, /// 0DH = 13 OutOfRange, /// 0EH = 14 Q2OutOfRange, /// 0FH = 15 MissingTest, /// 10H = 16 RFPowerRecordMissing, /// 11H = 17 HeadDisabledByUser, /// 12H = 18 WrongArguments, /// 13H = 19 } public partial class iPerlCommunicationForm : Form, GenericDevices.IHasCompleted { private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm)); protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData"); const int Hz2CorrFactorsAddr = 0x1875; /// Used by Reset2HzCorrection(...) and Write2HzCorrection(...) const int Q2CorrFactorsAddr = 0x1878; /// Used by ResetQ2Correction(...) and WriteQ2Correction(...) const int Q2CorrFactorsAddrLR = 0x1878; const int Q2CorrFactorsAddrRL = 0x1879; public const string ReadConfigurationStr = "Read configuration"; /// Example: "Read configuration" or "Read configuration if enabled" public const string SetTestModeStr = "Set Test mode"; /// Example: "Set Test mode" or "Set Test mode A0" (hexadecimal number is the required 'testModeConfig' public const string SetActiveModeStr = "Set Active mode"; public const string ReadCalibrationStr = "Read calibration"; public const string ReadCalibrationV4Str = "Read calibration_V4"; public const string WriteCalibrationFactorStr = "Write calibration factor"; public const string WriteCalibrationV4FactorsStr = "Write calibration_V4"; public const string NormalizeCalibrationFactorStr = "Normalize calibration factor"; public const string NormalizeCalibrationV4FactorsStr = "Normalize calibration_V4"; public const string GetDefaultQ2CorrectionsStr = "Get default Q2 corrections"; public const string ReadQ2CorrectionStr = "Read Q2 corrections"; public const string ResetQ2CorrectionStr = "Reset Q2 correction"; public const string WriteDefaultQ2CorrectionsStr = "Write default Q2 corrections"; public const string InitOrReadQ2CorrectionsStr = "Init or read Q2 corrections"; public const string WriteQ2CorrectionStr = "Write Q2 correction"; /// No arguments public const string WriteQ2CorrectionAltStr = "Write Q2 correction Alt"; /// No arguments public const string WriteQ2CorrectionGreeceStr = "Write Q2 correction Greece"; /// Arguments: test_name public const string WriteQ2CorrectionRLStr = "Write Q2 correction R-L"; /// Arguments: test_name public const string WriteQ2CorrectionLRStr = "Write Q2 correction L-R"; /// Arguments: test_name public const string WriteQ2CorrectionIncl05Str = "Write_Q2_correction_incl.-0,5..0,5%"; /// No arguments public const string WriteQ2CorrectionAltIncl05Str = "Write_Q2_correction_Alt_incl.-0,5..0,5%"; /// No arguments public const string WriteQ2CorrectionGreeceIncl05Str = "Write_Q2_correction_Greece_incl.-0,5..0,5%"; /// Arguments: test_name public const string WriteQ2CorrectionRLIncl05Str = "Write_Q2_correction_R-L_incl.-0,5..0,5%"; /// Arguments: test_name public const string WriteQ2CorrectionLRIncl05Str = "Write_Q2_correction_L-R_incl.-0,5..0,5%"; /// Arguments: test_name public const string UpdateBothQ2FactorsTestRLOnlyStr = "Update_both_Q2_factors_Test_RL_only"; /// No arguments public const string UpdateBothQ2FactorsTestLROnlyStr = "Update_both_Q2_factors_Test_LR_only"; /// No arguments public const string UpdateQ2CorrectionsStr = "Update Q2 corrections"; /// Arguments: R-L_test_name L-R_test_name public const string ConditnlUpdateQ2CorrectionsStr = "Conditional update of Q2 corrections"; /// Arguments: R-L_test_name L-R_test_name public const string ConditnlUpdateQ2CorrRLStr = "Conditional update of Q2 correction R-L"; /// Arguments: R-L_test_name public const string ConditnlUpdateQ2CorrLRStr = "Conditional update of Q2 correction L-R"; /// Arguments: L-R_test_name public const string Reset2HzCorrectionStr = "Reset 2Hz correction"; public const string Write2HzCorrectionStr = "Write 2Hz correction"; public const string DewaReworkRLStr = "DEWA rework R-L"; public const string DewaReworkLRStr = "DEWA rework L-R"; public const string StartTestingSealedMetersStr = "Start testing sealed meters"; public const string EndTestingSealedMetersStr = "End testing sealed meters"; public static Color DisabledColor = Color.DarkGray; public static Color OptoAndDirOKColor = Color.Green; public static Color OptoNokColor = Color.Orange; public static Color DirNokColor = Color.Red; #region DLL_Interface [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); [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); [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); [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); [DllImport("libRfid5.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion5(); [DllImport("libRfid5.dll", EntryPoint = "openPort")] static extern unsafe int openPort5(int comPort); [DllImport("libRfid5.dll", EntryPoint = "closePort")] static extern unsafe int closePort5(); [DllImport("libRfid5.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort5(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid5.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort5(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid6.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion6(); [DllImport("libRfid6.dll", EntryPoint = "openPort")] static extern unsafe int openPort6(int comPort); [DllImport("libRfid6.dll", EntryPoint = "closePort")] static extern unsafe int closePort6(); [DllImport("libRfid6.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort6(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid6.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort6(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid7.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion7(); [DllImport("libRfid7.dll", EntryPoint = "openPort")] static extern unsafe int openPort7(int comPort); [DllImport("libRfid7.dll", EntryPoint = "closePort")] static extern unsafe int closePort7(); [DllImport("libRfid7.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort7(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid7.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort7(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid8.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion8(); [DllImport("libRfid8.dll", EntryPoint = "openPort")] static extern unsafe int openPort8(int comPort); [DllImport("libRfid8.dll", EntryPoint = "closePort")] static extern unsafe int closePort8(); [DllImport("libRfid8.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort8(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid8.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort8(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid9.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion9(); [DllImport("libRfid9.dll", EntryPoint = "openPort")] static extern unsafe int openPort9(int comPort); [DllImport("libRfid9.dll", EntryPoint = "closePort")] static extern unsafe int closePort9(); [DllImport("libRfid9.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort9(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid9.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort9(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid10.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion10(); [DllImport("libRfid10.dll", EntryPoint = "openPort")] static extern unsafe int openPort10(int comPort); [DllImport("libRfid10.dll", EntryPoint = "closePort")] static extern unsafe int closePort10(); [DllImport("libRfid10.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort10(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid10.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort10(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid11.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion11(); [DllImport("libRfid11.dll", EntryPoint = "openPort")] static extern unsafe int openPort11(int comPort); [DllImport("libRfid11.dll", EntryPoint = "closePort")] static extern unsafe int closePort11(); [DllImport("libRfid11.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort11(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid11.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort11(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid12.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion12(); [DllImport("libRfid12.dll", EntryPoint = "openPort")] static extern unsafe int openPort12(int comPort); [DllImport("libRfid12.dll", EntryPoint = "closePort")] static extern unsafe int closePort12(); [DllImport("libRfid12.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort12(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid12.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort12(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid13.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion13(); [DllImport("libRfid13.dll", EntryPoint = "openPort")] static extern unsafe int openPort13(int comPort); [DllImport("libRfid13.dll", EntryPoint = "closePort")] static extern unsafe int closePort13(); [DllImport("libRfid13.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort13(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid13.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort13(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid14.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion14(); [DllImport("libRfid14.dll", EntryPoint = "openPort")] static extern unsafe int openPort14(int comPort); [DllImport("libRfid14.dll", EntryPoint = "closePort")] static extern unsafe int closePort14(); [DllImport("libRfid14.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort14(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid14.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort14(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid15.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion15(); [DllImport("libRfid15.dll", EntryPoint = "openPort")] static extern unsafe int openPort15(int comPort); [DllImport("libRfid15.dll", EntryPoint = "closePort")] static extern unsafe int closePort15(); [DllImport("libRfid15.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort15(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid15.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort15(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid16.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion16(); [DllImport("libRfid16.dll", EntryPoint = "openPort")] static extern unsafe int openPort16(int comPort); [DllImport("libRfid16.dll", EntryPoint = "closePort")] static extern unsafe int closePort16(); [DllImport("libRfid16.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort16(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid16.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort16(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid17.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion17(); [DllImport("libRfid17.dll", EntryPoint = "openPort")] static extern unsafe int openPort17(int comPort); [DllImport("libRfid17.dll", EntryPoint = "closePort")] static extern unsafe int closePort17(); [DllImport("libRfid17.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort17(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid17.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort17(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid18.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion18(); [DllImport("libRfid18.dll", EntryPoint = "openPort")] static extern unsafe int openPort18(int comPort); [DllImport("libRfid18.dll", EntryPoint = "closePort")] static extern unsafe int closePort18(); [DllImport("libRfid18.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort18(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid18.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort18(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid19.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion19(); [DllImport("libRfid19.dll", EntryPoint = "openPort")] static extern unsafe int openPort19(int comPort); [DllImport("libRfid19.dll", EntryPoint = "closePort")] static extern unsafe int closePort19(); [DllImport("libRfid19.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort19(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid19.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort19(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid20.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion20(); [DllImport("libRfid20.dll", EntryPoint = "openPort")] static extern unsafe int openPort20(int comPort); [DllImport("libRfid20.dll", EntryPoint = "closePort")] static extern unsafe int closePort20(); [DllImport("libRfid20.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort20(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid20.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort20(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid21.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion21(); [DllImport("libRfid21.dll", EntryPoint = "openPort")] static extern unsafe int openPort21(int comPort); [DllImport("libRfid21.dll", EntryPoint = "closePort")] static extern unsafe int closePort21(); [DllImport("libRfid21.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort21(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid21.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort21(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid22.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion22(); [DllImport("libRfid22.dll", EntryPoint = "openPort")] static extern unsafe int openPort22(int comPort); [DllImport("libRfid22.dll", EntryPoint = "closePort")] static extern unsafe int closePort22(); [DllImport("libRfid22.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort22(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid22.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort22(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid23.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion23(); [DllImport("libRfid23.dll", EntryPoint = "openPort")] static extern unsafe int openPort23(int comPort); [DllImport("libRfid23.dll", EntryPoint = "closePort")] static extern unsafe int closePort23(); [DllImport("libRfid23.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort23(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid23.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort23(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid24.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion24(); [DllImport("libRfid24.dll", EntryPoint = "openPort")] static extern unsafe int openPort24(int comPort); [DllImport("libRfid24.dll", EntryPoint = "closePort")] static extern unsafe int closePort24(); [DllImport("libRfid24.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort24(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid24.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort24(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid25.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion25(); [DllImport("libRfid25.dll", EntryPoint = "openPort")] static extern unsafe int openPort25(int comPort); [DllImport("libRfid25.dll", EntryPoint = "closePort")] static extern unsafe int closePort25(); [DllImport("libRfid25.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort25(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid25.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort25(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid26.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion26(); [DllImport("libRfid26.dll", EntryPoint = "openPort")] static extern unsafe int openPort26(int comPort); [DllImport("libRfid26.dll", EntryPoint = "closePort")] static extern unsafe int closePort26(); [DllImport("libRfid26.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort26(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid26.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort26(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid27.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion27(); [DllImport("libRfid27.dll", EntryPoint = "openPort")] static extern unsafe int openPort27(int comPort); [DllImport("libRfid27.dll", EntryPoint = "closePort")] static extern unsafe int closePort27(); [DllImport("libRfid27.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort27(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid27.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort27(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid28.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion28(); [DllImport("libRfid28.dll", EntryPoint = "openPort")] static extern unsafe int openPort28(int comPort); [DllImport("libRfid28.dll", EntryPoint = "closePort")] static extern unsafe int closePort28(); [DllImport("libRfid28.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort28(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid28.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort28(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid29.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion29(); [DllImport("libRfid29.dll", EntryPoint = "openPort")] static extern unsafe int openPort29(int comPort); [DllImport("libRfid29.dll", EntryPoint = "closePort")] static extern unsafe int closePort29(); [DllImport("libRfid29.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort29(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid29.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort29(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid30.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion30(); [DllImport("libRfid30.dll", EntryPoint = "openPort")] static extern unsafe int openPort30(int comPort); [DllImport("libRfid30.dll", EntryPoint = "closePort")] static extern unsafe int closePort30(); [DllImport("libRfid30.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort30(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid30.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort30(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid31.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion31(); [DllImport("libRfid31.dll", EntryPoint = "openPort")] static extern unsafe int openPort31(int comPort); [DllImport("libRfid31.dll", EntryPoint = "closePort")] static extern unsafe int closePort31(); [DllImport("libRfid31.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort31(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid31.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort31(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid32.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion32(); [DllImport("libRfid32.dll", EntryPoint = "openPort")] static extern unsafe int openPort32(int comPort); [DllImport("libRfid32.dll", EntryPoint = "closePort")] static extern unsafe int closePort32(); [DllImport("libRfid32.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort32(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid32.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort32(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid33.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion33(); [DllImport("libRfid33.dll", EntryPoint = "openPort")] static extern unsafe int openPort33(int comPort); [DllImport("libRfid33.dll", EntryPoint = "closePort")] static extern unsafe int closePort33(); [DllImport("libRfid33.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort33(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid33.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort33(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid34.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion34(); [DllImport("libRfid34.dll", EntryPoint = "openPort")] static extern unsafe int openPort34(int comPort); [DllImport("libRfid34.dll", EntryPoint = "closePort")] static extern unsafe int closePort34(); [DllImport("libRfid34.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort34(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid34.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort34(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid35.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion35(); [DllImport("libRfid35.dll", EntryPoint = "openPort")] static extern unsafe int openPort35(int comPort); [DllImport("libRfid35.dll", EntryPoint = "closePort")] static extern unsafe int closePort35(); [DllImport("libRfid35.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort35(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid35.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort35(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid36.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion36(); [DllImport("libRfid36.dll", EntryPoint = "openPort")] static extern unsafe int openPort36(int comPort); [DllImport("libRfid36.dll", EntryPoint = "closePort")] static extern unsafe int closePort36(); [DllImport("libRfid36.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort36(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid36.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort36(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid37.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion37(); [DllImport("libRfid37.dll", EntryPoint = "openPort")] static extern unsafe int openPort37(int comPort); [DllImport("libRfid37.dll", EntryPoint = "closePort")] static extern unsafe int closePort37(); [DllImport("libRfid37.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort37(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid37.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort37(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid38.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion38(); [DllImport("libRfid38.dll", EntryPoint = "openPort")] static extern unsafe int openPort38(int comPort); [DllImport("libRfid38.dll", EntryPoint = "closePort")] static extern unsafe int closePort38(); [DllImport("libRfid38.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort38(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid38.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort38(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid39.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion39(); [DllImport("libRfid39.dll", EntryPoint = "openPort")] static extern unsafe int openPort39(int comPort); [DllImport("libRfid39.dll", EntryPoint = "closePort")] static extern unsafe int closePort39(); [DllImport("libRfid39.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort39(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid39.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort39(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid40.dll", EntryPoint = "getDllVersion")] public static extern unsafe int getDllVersion40(); [DllImport("libRfid40.dll", EntryPoint = "openPort")] static extern unsafe int openPort40(int comPort); [DllImport("libRfid40.dll", EntryPoint = "closePort")] static extern unsafe int closePort40(); [DllImport("libRfid40.dll", EntryPoint = "readRequestPort")] static extern unsafe int readRequestPort40(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); [DllImport("libRfid40.dll", EntryPoint = "writeRequestPort")] static extern unsafe int writeRequestPort40(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms); /// /// Wrapper function with safe interface and unsafe body /// /// Water meter (iPerlHead) object /// Value returned by openPort(...) public static unsafe int OpenPort(IperlHead iperlHead) { if (iperlHead.DebugLevel != DebugMode.Normal) return 0; /// No function in debug mode switch (iperlHead.Position) { default: case 1: return openPort1(iperlHead.RfidComPortNr); case 2: return openPort2(iperlHead.RfidComPortNr); case 3: return openPort3(iperlHead.RfidComPortNr); case 4: return openPort4(iperlHead.RfidComPortNr); case 5: return openPort5(iperlHead.RfidComPortNr); case 6: return openPort6(iperlHead.RfidComPortNr); case 7: return openPort7(iperlHead.RfidComPortNr); case 8: return openPort8(iperlHead.RfidComPortNr); case 9: return openPort9(iperlHead.RfidComPortNr); case 10: return openPort10(iperlHead.RfidComPortNr); case 11: return openPort11(iperlHead.RfidComPortNr); case 12: return openPort12(iperlHead.RfidComPortNr); case 13: return openPort13(iperlHead.RfidComPortNr); case 14: return openPort14(iperlHead.RfidComPortNr); case 15: return openPort15(iperlHead.RfidComPortNr); case 16: return openPort16(iperlHead.RfidComPortNr); case 17: return openPort17(iperlHead.RfidComPortNr); case 18: return openPort18(iperlHead.RfidComPortNr); case 19: return openPort19(iperlHead.RfidComPortNr); case 20: return openPort20(iperlHead.RfidComPortNr); case 21: return openPort21(iperlHead.RfidComPortNr); case 22: return openPort22(iperlHead.RfidComPortNr); case 23: return openPort23(iperlHead.RfidComPortNr); case 24: return openPort24(iperlHead.RfidComPortNr); case 25: return openPort25(iperlHead.RfidComPortNr); case 26: return openPort26(iperlHead.RfidComPortNr); case 27: return openPort27(iperlHead.RfidComPortNr); case 28: return openPort28(iperlHead.RfidComPortNr); case 29: return openPort29(iperlHead.RfidComPortNr); case 30: return openPort30(iperlHead.RfidComPortNr); case 31: return openPort31(iperlHead.RfidComPortNr); case 32: return openPort32(iperlHead.RfidComPortNr); case 33: return openPort33(iperlHead.RfidComPortNr); case 34: return openPort34(iperlHead.RfidComPortNr); case 35: return openPort35(iperlHead.RfidComPortNr); case 36: return openPort36(iperlHead.RfidComPortNr); case 37: return openPort37(iperlHead.RfidComPortNr); case 38: return openPort38(iperlHead.RfidComPortNr); case 39: return openPort39(iperlHead.RfidComPortNr); case 40: return openPort40(iperlHead.RfidComPortNr); } } /// /// Wrapper function with safe interface and unsafe body /// /// Water meter (iPerlHead) object /// Value returned by openPort(...) public static unsafe int ClosePort(IperlHead iperlHead) { if (iperlHead.DebugLevel != DebugMode.Normal) return 0; /// No function in debug mode switch (iperlHead.Position) { default: case 1: return closePort1(); case 2: return closePort2(); case 3: return closePort3(); case 4: return closePort4(); case 5: return closePort5(); case 6: return closePort6(); case 7: return closePort7(); case 8: return closePort8(); case 9: return closePort9(); case 10: return closePort10(); case 11: return closePort11(); case 12: return closePort12(); case 13: return closePort13(); case 14: return closePort14(); case 15: return closePort15(); case 16: return closePort16(); case 17: return closePort17(); case 18: return closePort18(); case 19: return closePort19(); case 20: return closePort20(); case 21: return closePort21(); case 22: return closePort22(); case 23: return closePort23(); case 24: return closePort24(); case 25: return closePort25(); case 26: return closePort26(); case 27: return closePort27(); case 28: return closePort28(); case 29: return closePort29(); case 30: return closePort30(); case 31: return closePort31(); case 32: return closePort32(); case 33: return closePort33(); case 34: return closePort34(); case 35: return closePort35(); case 36: return closePort36(); case 37: return closePort37(); case 38: return closePort38(); case 39: return closePort39(); case 40: return closePort40(); } } /// /// Wrapper function with safe interface and unsafe body /// /// Water meter (iPerlHead) object /// Value returned by readRequestPort(...) public static unsafe int ReadRequestPort(IperlHead iperlHead, MessageID messageID, int offset, int length, out byte[] buffer, int timeout) { Thread.Sleep(Math.Max(250, cfg.DelayBetweenRetries)); if (iperlHead.DebugLevel != DebugMode.Normal) { /// /// Simulation /// if ((messageID == MessageID.Configuration) && (offset == 0) && (length == ConfigStruct.Length)) { buffer = new byte[ConfigStruct.Length] { 3, 3, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0, 1,2,3,4,5, 160, 0,0,0,0, 0,0, 0,0, 0,0 }; } else if ((messageID == MessageID.Calibration) && (offset == 0) && (length == CalibrationStruct.Length)) { buffer = new byte[CalibrationStruct.Length] { 3, 0, 150,10, 0, 0, 0,0, 0,0,0,0,0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,0,0, 1,2,3,4,5, 0, 0 }; } else if ((messageID == MessageID.Calibration) && (offset == 0) && (length == CalibrationStructV4.Length)) { buffer = new byte[CalibrationStructV4.Length] { 3, 0, 150,10, 0, 0, 0,0, 0,0,0,0,0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,0,0, 1,2,3,4,5, 0, 0, 150,10 }; } else if ((messageID == MessageID.Calibration) && (offset == 2) && (length == 2)) { buffer = new byte[2] { 150,10 }; } else if ((messageID == MessageID.Calibration) && (offset == 34) && (length == 2)) { buffer = new byte[2] { 150,10 }; } else if ((messageID == MessageID.MetrologyMemory) && (offset == Q2CorrFactorsAddr) && (length == 2)) { buffer = new byte[2] { 0, 0 }; } else { buffer = new byte[length]; } return iperlHead.Name.Equals("iPerl13") ? 2 : 0; /// Simulates an error on position 13 } buffer = new byte[length]; byte[] buf = new byte[200]; /// fixed (byte* pBuf = buf) { int retv; switch (iperlHead.Position) { default: case 1: retv = readRequestPort1(messageID, offset, length, pBuf, timeout); break; case 2: retv = readRequestPort2(messageID, offset, length, pBuf, timeout); break; case 3: retv = readRequestPort3(messageID, offset, length, pBuf, timeout); break; case 4: retv = readRequestPort4(messageID, offset, length, pBuf, timeout); break; case 5: retv = readRequestPort5(messageID, offset, length, pBuf, timeout); break; case 6: retv = readRequestPort6(messageID, offset, length, pBuf, timeout); break; case 7: retv = readRequestPort7(messageID, offset, length, pBuf, timeout); break; case 8: retv = readRequestPort8(messageID, offset, length, pBuf, timeout); break; case 9: retv = readRequestPort9(messageID, offset, length, pBuf, timeout); break; case 10: retv = readRequestPort10(messageID, offset, length, pBuf, timeout); break; case 11: retv = readRequestPort11(messageID, offset, length, pBuf, timeout); break; case 12: retv = readRequestPort12(messageID, offset, length, pBuf, timeout); break; case 13: retv = readRequestPort13(messageID, offset, length, pBuf, timeout); break; case 14: retv = readRequestPort14(messageID, offset, length, pBuf, timeout); break; case 15: retv = readRequestPort15(messageID, offset, length, pBuf, timeout); break; case 16: retv = readRequestPort16(messageID, offset, length, pBuf, timeout); break; case 17: retv = readRequestPort17(messageID, offset, length, pBuf, timeout); break; case 18: retv = readRequestPort18(messageID, offset, length, pBuf, timeout); break; case 19: retv = readRequestPort19(messageID, offset, length, pBuf, timeout); break; case 20: retv = readRequestPort20(messageID, offset, length, pBuf, timeout); break; case 21: retv = readRequestPort21(messageID, offset, length, pBuf, timeout); break; case 22: retv = readRequestPort22(messageID, offset, length, pBuf, timeout); break; case 23: retv = readRequestPort23(messageID, offset, length, pBuf, timeout); break; case 24: retv = readRequestPort24(messageID, offset, length, pBuf, timeout); break; case 25: retv = readRequestPort25(messageID, offset, length, pBuf, timeout); break; case 26: retv = readRequestPort26(messageID, offset, length, pBuf, timeout); break; case 27: retv = readRequestPort27(messageID, offset, length, pBuf, timeout); break; case 28: retv = readRequestPort28(messageID, offset, length, pBuf, timeout); break; case 29: retv = readRequestPort29(messageID, offset, length, pBuf, timeout); break; case 30: retv = readRequestPort30(messageID, offset, length, pBuf, timeout); break; case 31: retv = readRequestPort31(messageID, offset, length, pBuf, timeout); break; case 32: retv = readRequestPort32(messageID, offset, length, pBuf, timeout); break; case 33: retv = readRequestPort33(messageID, offset, length, pBuf, timeout); break; case 34: retv = readRequestPort34(messageID, offset, length, pBuf, timeout); break; case 35: retv = readRequestPort35(messageID, offset, length, pBuf, timeout); break; case 36: retv = readRequestPort36(messageID, offset, length, pBuf, timeout); break; case 37: retv = readRequestPort37(messageID, offset, length, pBuf, timeout); break; case 38: retv = readRequestPort38(messageID, offset, length, pBuf, timeout); break; case 39: retv = readRequestPort39(messageID, offset, length, pBuf, timeout); break; case 40: retv = readRequestPort40(messageID, offset, length, pBuf, timeout); break; } for (int i = 0; i < length; i++) buffer[i] = buf[i]; /// /// Logging /// string name = string.Format("{0}({1})", iperlHead.Name, iperlHead.SerialNr); if ((messageID == MessageID.Configuration) && (offset == 0) && (length == 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) && (length == CalibrationStruct.Length)) rfidDataLogger.InfoFormat("{0}: ReadRequestPort({1},...) returned {2} {3}", name, messageID, retv, (retv != 0) ? "!" : CalibrationStruct.FromByteArray(buffer).ToString()); else if ((messageID == MessageID.Calibration) && (offset == 0) && (length == CalibrationStructV4.Length)) rfidDataLogger.InfoFormat("{0}: ReadRequestPort({1},...) returned {2} {3}", name, messageID, retv, (retv != 0) ? "!" : CalibrationStructV4.FromByteArray(buffer).ToString()); else if ((messageID == MessageID.Calibration) && (offset == 2) && (length == 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 if ((messageID == MessageID.Calibration) && (offset == 34) && (length == 2)) rfidDataLogger.InfoFormat("{0}: ReadRequestPort({1},34,2,...) returned {2} {3}", name, messageID, retv, (retv != 0) ? "!" : string.Format("CalLNA={0}", buf[0] + 256 * buf[1])); else if ((messageID == MessageID.MetrologyMemory) && (offset == Q2CorrFactorsAddr) && (length == 2)) rfidDataLogger.InfoFormat("{0}: ReadRequestPort({1},6264,2,...) returned {2} {3}", name, messageID, retv, (retv != 0) ? "!" : string.Format("LR={0} RL={1}", (int)buf[0], (int)buf[1])); else rfidDataLogger.InfoFormat("{0}: ReadRequestPort({1}, {2}, {3}, ...) returned {4} {5}", name, messageID, offset, length, retv, (retv != 0) ? "!" : ""); return retv; } } /// /// Wrapper function with safe interface and unsafe body /// /// Water meter (iPerlHead) object /// Value returned by writeRequestPort(...) public static unsafe int WriteRequestPort(IperlHead iperlHead, MessageID messageID, int offset, int length, byte[] buffer, int timeout) { Thread.Sleep(Math.Max(250, cfg.DelayBetweenRetries)); if (iperlHead.DebugLevel != DebugMode.Normal) return 0; fixed (byte* pBuf = buffer) { int retv; switch (iperlHead.Position) { default: case 1: retv = writeRequestPort1(messageID, offset, length, pBuf, timeout); break; case 2: retv = writeRequestPort2(messageID, offset, length, pBuf, timeout); break; case 3: retv = writeRequestPort3(messageID, offset, length, pBuf, timeout); break; case 4: retv = writeRequestPort4(messageID, offset, length, pBuf, timeout); break; case 5: retv = writeRequestPort5(messageID, offset, length, pBuf, timeout); break; case 6: retv = writeRequestPort6(messageID, offset, length, pBuf, timeout); break; case 7: retv = writeRequestPort7(messageID, offset, length, pBuf, timeout); break; case 8: retv = writeRequestPort8(messageID, offset, length, pBuf, timeout); break; case 9: retv = writeRequestPort9(messageID, offset, length, pBuf, timeout); break; case 10: retv = writeRequestPort10(messageID, offset, length, pBuf, timeout); break; case 11: retv = writeRequestPort11(messageID, offset, length, pBuf, timeout); break; case 12: retv = writeRequestPort12(messageID, offset, length, pBuf, timeout); break; case 13: retv = writeRequestPort13(messageID, offset, length, pBuf, timeout); break; case 14: retv = writeRequestPort14(messageID, offset, length, pBuf, timeout); break; case 15: retv = writeRequestPort15(messageID, offset, length, pBuf, timeout); break; case 16: retv = writeRequestPort16(messageID, offset, length, pBuf, timeout); break; case 17: retv = writeRequestPort17(messageID, offset, length, pBuf, timeout); break; case 18: retv = writeRequestPort18(messageID, offset, length, pBuf, timeout); break; case 19: retv = writeRequestPort19(messageID, offset, length, pBuf, timeout); break; case 20: retv = writeRequestPort20(messageID, offset, length, pBuf, timeout); break; case 21: retv = writeRequestPort21(messageID, offset, length, pBuf, timeout); break; case 22: retv = writeRequestPort22(messageID, offset, length, pBuf, timeout); break; case 23: retv = writeRequestPort23(messageID, offset, length, pBuf, timeout); break; case 24: retv = writeRequestPort24(messageID, offset, length, pBuf, timeout); break; case 25: retv = writeRequestPort25(messageID, offset, length, pBuf, timeout); break; case 26: retv = writeRequestPort26(messageID, offset, length, pBuf, timeout); break; case 27: retv = writeRequestPort27(messageID, offset, length, pBuf, timeout); break; case 28: retv = writeRequestPort28(messageID, offset, length, pBuf, timeout); break; case 29: retv = writeRequestPort29(messageID, offset, length, pBuf, timeout); break; case 30: retv = writeRequestPort30(messageID, offset, length, pBuf, timeout); break; case 31: retv = writeRequestPort31(messageID, offset, length, pBuf, timeout); break; case 32: retv = writeRequestPort32(messageID, offset, length, pBuf, timeout); break; case 33: retv = writeRequestPort33(messageID, offset, length, pBuf, timeout); break; case 34: retv = writeRequestPort34(messageID, offset, length, pBuf, timeout); break; case 35: retv = writeRequestPort35(messageID, offset, length, pBuf, timeout); break; case 36: retv = writeRequestPort36(messageID, offset, length, pBuf, timeout); break; case 37: retv = writeRequestPort37(messageID, offset, length, pBuf, timeout); break; case 38: retv = writeRequestPort38(messageID, offset, length, pBuf, timeout); break; case 39: retv = writeRequestPort39(messageID, offset, length, pBuf, timeout); break; case 40: retv = writeRequestPort40(messageID, offset, length, pBuf, timeout); break; } /// /// Logging /// string name = string.Format("{0}({1})", iperlHead.Name, iperlHead.SerialNr); if (length == 1) rfidDataLogger.InfoFormat("{0}: WriteRequestPort({2}, {3}, {4}, {5}) returned {1} {6}", name, retv, messageID, offset, length, pBuf[0].ToString("X2"), (retv != 0) ? "!" : ""); else if (length == 2) { if (messageID == MessageID.Calibration && offset == 2) { UInt16 calibFactor = (UInt16)(pBuf[0] + 256 * pBuf[1]); rfidDataLogger.InfoFormat("{0}: WriteRequestPort(Cal={1}) returned {2} {3}", name, calibFactor, retv, (retv != 0) ? "!" : ""); } else if (messageID == MessageID.Calibration && offset == 34) { UInt16 calibFactor = (UInt16)(pBuf[0] + 256 * pBuf[1]); rfidDataLogger.InfoFormat("{0}: WriteRequestPort(CalLNA={1}) returned {2} {3}", name, calibFactor, retv, (retv != 0) ? "!" : ""); } else rfidDataLogger.InfoFormat("{0}: WriteRequestPort({2}, {3}, {4}, {5} {6}) returned {1} {7}", name, retv, messageID, offset, length, pBuf[0].ToString("X2"), pBuf[1].ToString("X2"), (retv != 0) ? "!" : ""); } else rfidDataLogger.InfoFormat("{0}: WriteRequestPort({2}, {3}, {4}, {5} {6} ...) returned {1} {7}", name, retv, messageID, offset, length, pBuf[0].ToString("X2"), pBuf[1].ToString("X2"), (retv != 0) ? "!" : ""); return retv; } } #endregion DLL_Interface readonly bool checkBoxesEditMode; DateTime startTime; int startTimeSec; // Set to 'true' when the form closes public bool Completed { get { return formCompleted; } } bool formCompleted; bool forcedClose; /// Set in the forced close handler /// Number of text boxes for serial numbers public int WaterMetersCount; const int MaxTextBoxesCount = 48; int textBoxesCount; Label[] labels; PictureBox[] counters; TextBox[] messages; CheckBoxImage[] checkBoxes; static int[] ckbIndex; static bool[] ckbState; static IList iperlHeads; static IList waterMeterPositions0; /// keeps original 0-based indices in RegisterReaders list static int commonWMType; /// /// RFID multiplexer PCB / RFID serial port and worker thread related variables /// static TestMethod testMethod; static TestMethodCfg cfg; static IList tests; static IList multiTestParams; static int currentActivityStep; static int currentGroup; /// form -> worker thread (0 = none) static int lastGroup; static int completedCommCount; /// Number of completed communication steps static IList workerThreads; static IList muxBrdOrGroup14Nrs; static bool stopWorkerThreads; /// form -> worker thread /// Parameterless constructor (without watermeters, threads) public iPerlCommunicationForm() { InitializeComponent(); } /// /// Constructor for checkBox states (active/inactive iPerl head) editing. /// /// Initial check box states public iPerlCommunicationForm(bool isCheckBoxesEditMode) : this() { if (isCheckBoxesEditMode) { checkBoxesEditMode = true; saveButton.Visible = true; activityLabel.Text = Strings.Optical_heads; ShuffleTextBoxes(ProcessData.WMsCount, ProcessData.LineSize); } } /// /// Constructor for one iPerlCommunication 'test' /// /// Number of text boxes for serial numbers public iPerlCommunicationForm(TestMethod testMethod, Test test, iPerlCommunicationParams testParams) : this(testMethod, new List { test }, new List { testParams }) { } /// /// Constructor for multiple iPerlCommunication 'tests' /// /// Number of text boxes for serial numbers public iPerlCommunicationForm(TestMethod testMethod, IList tests, IList multiTestParams) : this() { checkBoxesEditMode = false; iPerlCommunicationForm.testMethod = testMethod; iPerlCommunicationForm.cfg = testMethod.Cfg as TestMethodCfg; iPerlCommunicationForm.tests = tests; iPerlCommunicationForm.multiTestParams = multiTestParams; if (multiTestParams.Count > 0) { ProcessData.RegisterReaders = StateMachine.GetMetersPath(tests[0]).RegisterReaders; activityLabel.Text = multiTestParams[0].Activity; foreach (var p in multiTestParams) { if (p.Activity.ToLower() == GetDefaultQ2CorrectionsStr.ToLower()) { /// Reset IsQ2PreCorrectionCalculated that is used for synchronization/to prevent double REST call ProcessData.IsQ2PreCorrectionCalculated = false; commonWMType = 0; break; } } } PrepareForTestsActivities(); } void PrepareForTestsActivities() { startTime = DateTime.Now; startTimeSec = StateMachine.Time; /// Attach to 'CommCompleted' handler CommCompletedHandler += delegate(object sender, CommCompletedEventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(DoOnCommCompleted), sender, args); } else DoOnCommCompleted(sender, args); }; /// Attach to 'AllCompleted' handler AllCompletedHandler += delegate(object sender, AllCompletedEventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(DoOnAllCompleted), sender, args); } else DoOnAllCompleted(sender, args); }; formCompleted = false; StartForceCloseHandler(); iperlHeads = new List(); waterMeterPositions0 = new List(); /// for (int wmPos = 0; wmPos < ProcessData.RegisterReaders.Length; wmPos++) { IperlHead iperlHead = ProcessData.RegisterReaders[wmPos] as IperlHead; if (iperlHead != null) { iperlHeads.Add(iperlHead); waterMeterPositions0.Add(wmPos); } } WaterMetersCount = iperlHeads.Count; ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize); /// /// Prepare worker threads, 'rfidPortNrs', 'lastGroup', etc.. /// currentActivityStep = 0; currentGroup = 0; completedCommCount = 0; stopWorkerThreads = false; /// group numbers are >=1, lastGroup == 0 means there is no group lastGroup = 0; foreach (var iPerl in iPerlCommunicationForm.iperlHeads) { if (iPerl.Group > lastGroup) lastGroup = iPerl.Group; } workerThreads = new List(); for (int i = 0; i < cfg.NrThreads; i++) { Thread thread = new Thread(Worker); thread.CurrentCulture = CultureInfo.CurrentCulture; thread.CurrentUICulture = CultureInfo.CurrentUICulture; workerThreads.Add(thread); } muxBrdOrGroup14Nrs = new List(); foreach (var iPerl in iPerlCommunicationForm.iperlHeads) { if (!muxBrdOrGroup14Nrs.Contains(iPerl.MuxBoardNrOrGroup14)) muxBrdOrGroup14Nrs.Add(iPerl.MuxBoardNrOrGroup14); } log.WarnFormat("nrThreads = {0}", workerThreads.Count); } /// /// Make sure the layout of labels/text boxes on the screen /// corresponds to the layout of watermeters of the test bench. /// /// Number of watermeters /// Number of watermeters in one line void ShuffleTextBoxes(int wmsCount, int lineSize) { labels = new Label[MaxTextBoxesCount] { 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, }; counters = new PictureBox[MaxTextBoxesCount] { 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, }; messages = new TextBox[MaxTextBoxesCount] { 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, }; checkBoxes = new CheckBoxImage[MaxTextBoxesCount] { checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5, checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10, checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15, checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20, checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25, checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30, checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35, checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40, checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45, checkBoxImage46, checkBoxImage47, checkBoxImage48, }; ckbIndex = new int[MaxTextBoxesCount]; ckbState = new bool[MaxTextBoxesCount]; textBoxesCount = MaxTextBoxesCount; /// if (wmsCount < textBoxesCount && lineSize > 0) { int nrLines = (wmsCount + lineSize - 1) / lineSize; int gap = (textBoxesCount - wmsCount) / nrLines; for (int i = 0; i < ckbIndex.Length; i++) { ckbIndex[i] = -1; /// Initialize with invalid indices } int dest = 0; for (int l = 0; l < nrLines; l++) { for (int i = 0; i < lineSize; i++) { int origin = l * lineSize + l * gap + i; labels[dest] = labels[origin]; counters[dest] = counters[origin]; messages[dest] = messages[origin]; checkBoxes[dest] = checkBoxes[origin]; ckbIndex[origin] = dest; dest++; } } textBoxesCount = wmsCount; } int count = checkBoxesEditMode ? textBoxesCount : Math.Min(textBoxesCount, iperlHeads.Count); for (int j = 0; j < count; j++) { labels[j].Text = (j + 1).ToString(); } ResizeDlgToFitEnabledControls(); } void ResizeDlgToFitEnabledControls() { 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 + 50; Height = yMax + 60; } void Localize() { Text = checkBoxesEditMode ? Strings.Optical_heads : Strings.Water_Meter_States; saveButton.Text = Strings.Save; sampleLabel1.Text = Strings.Direction_and_pulses_are_OK; sampleLabel2.Text = Strings.There_are_no_opto_pulses; sampleLabel3.Text = Strings.Direction_is_NOK; samplePictureBox1.BackColor = OptoAndDirOKColor; samplePictureBox2.BackColor = OptoNokColor; samplePictureBox3.BackColor = DirNokColor; } private void iPerlCommunicationForm_Load(object sender, EventArgs e) { Localize(); if (checkBoxesEditMode) { /// Check box edit mode => Hide explanation of activity colours sampleLabel1.Visible = false; sampleLabel2.Visible = false; sampleLabel3.Visible = false; samplePictureBox1.Visible = false; samplePictureBox2.Visible = false; samplePictureBox3.Visible = false; } /// /// Set checkbox states accroding to iPerlHeads[i].Disabled states /// for (int i = 0; i < textBoxesCount; i++) { labels[i].Visible = counters[i].Visible = messages[i].Visible = checkBoxes[i].Visible = true; if (!checkBoxesEditMode && (iperlHeads[i] == null || iperlHeads[i].Disabled)) { /// iPerl position i+1 is disabled checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = false; counters[i].BackColor = DisabledColor; messages[i].Text = Strings.Head_was_disabled_by_the_user; } else { /// iPerl position i+1 is enabled checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = true; messages[i].Text = "---"; } } /// /// Set location and checkbox states to values stored in local settings /// TBF.LocalSettings ls = Program.LocalSettings; Left = (ls.iPerlCommunicationsFormLeft != 0) ? ls.iPerlCommunicationsFormLeft : 150; Top = (ls.iPerlCommunicationsFormTop != 0) ? ls.iPerlCommunicationsFormTop : 150; SetCheckBoxStates(ls.OptoHeadsEnabled); if (!checkBoxesEditMode) { /// Regular activity (not a checkbox edit mode invoked from TBF menu) /// Reset opto-data indication for (int i = 0; i < iperlHeads.Count; i++) { counters[i].BackColor = OptoNokColor; } /// Start communication process by incrementing 'currentGroup'. currentGroup++; int wtId = 0; foreach (var wt in workerThreads) { wt.Start(new Boxes.IntBox(wtId++)); /// Start worker threads !!! } } } private void NormalClose() { CommCompletedHandler = null; AllCompletedHandler = null; if (multiTestParams != null && multiTestParams.Count > 0 && !multiTestParams[0].SimultWithNext) /// RFID Communication at the end of the cycle does not influence the result { UpdateRfidCommResult(tests); /// TODO: Pass the test info in a correct way } long checkboxStates = GetCheckBoxStates(); if (Program.LocalSettings.iPerlCommunicationsFormLeft != Location.X || Program.LocalSettings.iPerlCommunicationsFormTop != Location.Y || Program.LocalSettings.OptoHeadsEnabled != checkboxStates) { /// Update local settings Program.LocalSettings.iPerlCommunicationsFormLeft = Location.X; Program.LocalSettings.iPerlCommunicationsFormTop = Location.Y; Program.LocalSettings.OptoHeadsEnabled = checkboxStates; Program.LocalSettings.Save(); } formCompleted = true; DialogResult = DialogResult.OK; Close(); } #region Forced close handling public void StartForceCloseHandler() { UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(OnForceClose), sender, args); } else OnForceClose(sender, args); }; } void OnForceClose(object sender, EventArgs args) { CommCompletedHandler = null; AllCompletedHandler = null; stopWorkerThreads = true; forcedClose = true; DialogResult = DialogResult.Cancel; Close(); } #endregion /// /// Worker thread /// /// Thread ID (integer) wrapped into IntBox void Worker(object threadData) { int threadID = (threadData as Boxes.IntBox).Val; int activityStep = 0; /// activity step > 0 in case multiTestParams are used for (int i = 0; i < multiTestParams.Count; i++ ) { Test currentTest = tests[i]; iPerlCommunicationParams currentTestParams = multiTestParams[i]; string currentActivity = currentTestParams.Activity; /// Current activity TBF.UiBridge.TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 10, 0, 140, 0, 0, 0 }); TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[i], Progress.JustStarted)); if (threadID == 0) { /// Check whether previous activity was 'Set test mode A0' or 'A4' if (i > 0 && multiTestParams[i - 1].Activity.ToLower().Contains(SetTestModeStr.ToLower()) && !multiTestParams[i - 1].Activity.Contains("80")) { /// Start processing of opto-datastreams from all iPERL-s int count = 0; for (int wmNr0 = 0; wmNr0 < iperlHeads.Count; wmNr0++) { Results.Entities.WaterMeter wm = (ProcessData.BatchRslts.Batch.WaterMeters != null && ProcessData.BatchRslts.Batch.WaterMeters.Count > wmNr0) ? ProcessData.BatchRslts.Batch.WaterMeters[wmNr0] : null; IperlHead ihead = iperlHeads[wmNr0]; if (ihead != null && wm != null && !wm.Disabled) { lock (ihead) { ihead.StartDataStreamProcessing(); count++; } } } log.WarnFormat("End of activity '{0}', StartDataStreamProcessing() of {1} heads was called.", multiTestParams[i - 1].Activity, count); } /// A new activity starts - information into RFID data log rfidDataLogger.InfoFormat(""); rfidDataLogger.WarnFormat("Activity = {0}", currentActivity); rfidDataLogger.InfoFormat(""); } for (int group = 1; group <= lastGroup; group++) { /// Synchronize with QuidoRS and other threads while (((group != currentGroup) || (activityStep != currentActivityStep)) && !stopWorkerThreads) { Thread.Sleep(50); } if (stopWorkerThreads) break; #if TURA_SPECIAL int threadIx = threadID; /// Just one thread for TURA_SPECIAL #else for (int threadIx = threadID; threadIx < threadID + 4; threadIx += cfg.NrThreads) #endif { bool wmFound = false; for (int wmNr0 = 0; wmNr0 < iperlHeads.Count; wmNr0++) { IperlHead ihead = iperlHeads[wmNr0]; if ((ihead.Group == group) && (threadIx < muxBrdOrGroup14Nrs.Count) && (ihead.MuxBoardNrOrGroup14 == muxBrdOrGroup14Nrs[threadIx])) { wmFound = true; Results.Entities.WaterMeter wm = null; if (ProcessData.BatchRslts.Batch.WaterMeters != null) { foreach (var w in ProcessData.BatchRslts.Batch.WaterMeters) { if (w.WMPosition == wmNr0 + 1) { wm = w; break; } } } CommErr error; string resultStr = string.Empty; /// /// RFID communication activity call /// if ((ihead == null) || ihead.Disabled || !ckbState[wmNr0]) error = CommErr.HeadDisabledByUser; #if IPERL else if (currentActivity.ToLower().Contains(SetTestModeStr.ToLower())) error = SetTestMode(threadID, ihead, ref resultStr); else if (currentActivity.ToLower().Equals(SetActiveModeStr.ToLower())) error = SetActiveMode(threadID, ihead, ref resultStr); /// /// RFID communication functions below require a reference to water meter entity (wm != null) /// else if (wm == null) error = CommErr.CommFailed; else if (currentActivity.ToLower().Contains(ReadConfigurationStr.ToLower())) error = ReadConfiguration(ihead, wm, ref resultStr); else if (currentActivity.ToLower() == ReadCalibrationStr.ToLower()) error = ReadCalibration(ihead, wm, ref resultStr); else if (currentActivity.ToLower() == ReadCalibrationV4Str.ToLower()) error = ReadCalibrationV4(ihead, wm, ref resultStr); else if (currentActivity.ToLower().Contains(WriteCalibrationFactorStr.ToLower())) error = WriteCalibrationFactor(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower().Contains(WriteCalibrationV4FactorsStr.ToLower())) error = WriteCalibrationV4Factors(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == NormalizeCalibrationFactorStr.ToLower()) error = NormalizeCalibrationFactor(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == NormalizeCalibrationV4FactorsStr.ToLower()) error = NormalizeCalibrationV4Factors(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == ReadQ2CorrectionStr.ToLower()) error = ReadQ2Correction(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == ResetQ2CorrectionStr.ToLower()) error = ResetQ2Correction(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == WriteDefaultQ2CorrectionsStr.ToLower()) error = WriteDefaultQ2Corrections(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == InitOrReadQ2CorrectionsStr.ToLower()) error = InitOrReadQ2Corrections(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == WriteQ2CorrectionStr.ToLower()) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Standard, null); else if (currentActivity.ToLower() == WriteQ2CorrectionAltStr.ToLower()) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Dewa, null); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionGreeceStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Greece, currentActivity.Substring(WriteQ2CorrectionGreeceStr.Length).Trim()); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionRLStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.RL, currentActivity.Substring(WriteQ2CorrectionRLStr.Length).Trim()); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionLRStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.LR, currentActivity.Substring(WriteQ2CorrectionLRStr.Length).Trim()); else if (currentActivity.ToLower() == WriteQ2CorrectionIncl05Str.ToLower()) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Standard_incl_05, null); else if (currentActivity.ToLower() == WriteQ2CorrectionAltIncl05Str.ToLower()) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Dewa_incl_05, null); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionGreeceIncl05Str.ToLower()))error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Greece_incl_05, currentActivity.Substring(WriteQ2CorrectionGreeceIncl05Str.Length).Trim()); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionRLIncl05Str.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.RL_incl_05, currentActivity.Substring(WriteQ2CorrectionRLIncl05Str.Length).Trim()); else if (currentActivity.ToLower().Contains(WriteQ2CorrectionLRIncl05Str.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.LR_incl_05, currentActivity.Substring(WriteQ2CorrectionLRIncl05Str.Length).Trim()); else if (currentActivity.ToLower().Contains(UpdateBothQ2FactorsTestRLOnlyStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.UpdateBothQ2FactorsTestRLDir, null); else if (currentActivity.ToLower().Contains(UpdateBothQ2FactorsTestLROnlyStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.UpdateBothQ2FactorsTestLRDir, null); else if (currentActivity.ToLower().Contains(UpdateQ2CorrectionsStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.Update, currentActivity.Substring(UpdateQ2CorrectionsStr.Length).Trim()); else if (currentActivity.ToLower().Contains(ConditnlUpdateQ2CorrectionsStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.ConditionalUpdate, currentActivity.Substring(ConditnlUpdateQ2CorrectionsStr.Length).Trim()); else if (currentActivity.ToLower().Contains(ConditnlUpdateQ2CorrRLStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.ConditionalUpdateRL, currentActivity.Substring(ConditnlUpdateQ2CorrRLStr.Length).Trim()); else if (currentActivity.ToLower().Contains(ConditnlUpdateQ2CorrLRStr.ToLower())) error = CalculateAndWriteQ2Corrections(threadID, ihead, wm, currentTest, ref resultStr, Q2CorrType.ConditionalUpdateLR, currentActivity.Substring(ConditnlUpdateQ2CorrLRStr.Length).Trim()); else if (currentActivity.ToLower() == Reset2HzCorrectionStr.ToLower()) error = Reset2HzCorrection(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == Write2HzCorrectionStr.ToLower()) error = Write2HzCorrection(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == GetDefaultQ2CorrectionsStr.ToLower()) error = GetQ2PreCorrectionsFormRest(threadID, ihead, wm, ref resultStr); else if (currentActivity.ToLower() == DewaReworkRLStr.ToLower()) error = DewaRework(ihead, wm, FlowDir.R_L, ref resultStr); else if (currentActivity.ToLower() == DewaReworkLRStr.ToLower()) error = DewaRework(ihead, wm, FlowDir.L_R, ref resultStr); else if (currentActivity.ToLower().Contains(StartTestingSealedMetersStr.ToLower())) error = StartTestingSealedMeter(ihead, wm, ref resultStr); else if (currentActivity.ToLower().Contains(EndTestingSealedMetersStr.ToLower())) error = EndTestingSealedMeter(ihead, wm, ref resultStr); #endif else { error = CommErr.None; ConditionID id = ConditionID.Count; #if IPERL for (id = ConditionID.A; id < ConditionID.Count; id++) { if (currentActivity.ToLower() == string.Format(SequenceConditionOp.ConditionNameFmt, id).ToLower()) { error = SetIperlCommMilestoneReached(testMethod, id, ref resultStr); break; } } #endif if (id == ConditionID.Count) { resultStr = "Invalid activity"; /// No activity or milestone } } /// /// Process the result of RFID communication activity /// if (error == CommErr.HeadDisabledByUser || !ckbState[wmNr0]) { OnCommCompleted(null, new CommCompletedEventArgs(threadID, wmNr0, ihead, wm, Strings.Head_was_disabled_by_the_user, CommErr.HeadDisabledByUser)); } else if (error == CommErr.None) { OnCommCompleted(null, new CommCompletedEventArgs(threadID, wmNr0, ihead, wm, resultStr, CommErr.None)); } else if ((error == CommErr.OutOfRange) || (error == CommErr.Q2OutOfRange)) { OnCommCompleted(null, new CommCompletedEventArgs(threadID, wmNr0, ihead, wm, resultStr, CommErr.CommFailed)); } else if (ihead.CommFailed || (error == CommErr.CommFailed)) { ihead.CommFailed = true; if (wm != null && (wm.ResultCode & (int)Results.Entities.ResultCode.RfidErrorCodeMask) == 0) { wm.ResultCode |= (((int)error << 16) | ((int)tests[i].ItemNr << 20)); } OnCommCompleted(null, new CommCompletedEventArgs(threadID, wmNr0, ihead, wm, Strings.RFID_communication_failed, error)); } else { ihead.CommFailed = true; if (wm != null && (wm.ResultCode & (int)Results.Entities.ResultCode.RfidErrorCodeMask) == 0) { wm.ResultCode |= (((int)error << 16) | ((int)tests[i].ItemNr << 20)); } string failureCauseLocal = string.Format(Strings.failed_0_1_exclamation, currentActivity, error); rfidDataLogger.ErrorFormat("Group={0}, Board={1}, {2}", currentGroup, ihead.MuxBoardNrOrGroup14, failureCauseLocal); OnCommCompleted(null, new CommCompletedEventArgs(threadID, wmNr0, ihead, wm, failureCauseLocal, error)); } break; } TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[i], Progress.FlowSetting)); } if (!wmFound) { OnCommCompleted(null, new CommCompletedEventArgs(threadID, -1, null, null, string.Empty, CommErr.None)); /// Send negative wmNr } if (stopWorkerThreads) break; } if (stopWorkerThreads) break; } /// for (int group TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[i], Progress.Completed)); activityStep++; if (stopWorkerThreads) break; } } #region Communication functions #if IPERL /// /// Read a complete configuration structure of the watermeter /// /// iPERL head object /// Water meter object /// String passed to caller /// true on success static CommErr ReadConfiguration(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { /// /// The activity is "Read configuration" (this enables the watermeter, resets error flag) /// or "Read configuration if enabled" (this keeps the error flag). /// if (!multiTestParams[currentActivityStep].Activity.ToLower().Contains(" if enabled")) { ihead.CommFailed = false; } if (ihead.CommFailed) return CommErr.CommFailed; ihead.ConfigStruct = null; /// Clear previous ConfigStruct, avoid reuse of (not anymore valid) PCB Number if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Read; int readRetVal = 0; /// Read configuration byte[] config = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { readRetVal = ReadRequestPort(ihead, MessageID.Configuration, 0, ConfigStruct.Length, out config, cfg.CommTimeout); if (readRetVal == 0) { error = CommErr.None; ihead.ConfigStruct = ConfigStruct.FromByteArray(config); resultStr = ihead.ConfigStruct.ToString(1); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } ClosePort(ihead); /// Close RFID port return error + Math.Max(0, Math.Min(readRetVal, 4)); } /// /// 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. /// /// Thread ID passed to RFID communication functions /// iPERL head object /// String passed to caller /// true on success static CommErr SetTestMode(int threadId, IperlHead ihead, ref string resultStr) { if (ihead.CommFailed || ihead.ConfigStruct == null) return CommErr.CommFailed; Byte testModeConfig = 0xA0; /// Default value /// if (multiTestParams[currentActivityStep].Activity.Length > SetTestModeStr.Length) { string testModeConfigStr = multiTestParams[currentActivityStep].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 } } if (ihead.ConfigStruct.MeterState == MeterState.Test && ihead.ConfigStruct.TestModeConfig == testModeConfig) { /// Already in the correct test mode resultStr = "Already " + ihead.ConfigStruct.ToString(1); return CommErr.None; } /// Communication necessary if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.None; if (error==CommErr.None && (ihead.ConfigStruct.TestModeConfig != testModeConfig) && (ihead.ConfigStruct.MeterState != MeterState.Active)) { /// Switch to Active mode in order to change TestModeConfig error = CommErr.CmdActive; byte[] cmd = new byte[1] { (byte)Command.SetActiveMode }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Command, 0, 1, cmd, cfg.CommTimeout)) { error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// Delay min. 250 ms Thread.Sleep(Math.Max(250, cfg.DelayBetweenRetries)); } if (error == CommErr.None && (ihead.ConfigStruct.TestModeConfig != testModeConfig)) { /// Change the TestModeConfig if necessary error = CommErr.Write; byte[] tstMdCfg = new byte[1] { testModeConfig }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Configuration, 21, 1, tstMdCfg, cfg.CommTimeout)) { ihead.ConfigStruct.Update(21, tstMdCfg); error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// Delay min. 250 ms Thread.Sleep(Math.Max(250, cfg.DelayBetweenRetries)); } if (error == CommErr.None) { /// Switch to test mode error = CommErr.CmdTest; byte[] cmd = new byte[1] { (byte)Command.SetTestMode }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Command, 0, 1, cmd, cfg.CommTimeout)) { error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// Delay min. 250 ms Thread.Sleep(Math.Max(250, cfg.DelayBetweenRetries)); } /// Now the meter should be in the Test mode ... verify if (error == CommErr.None) { /// Verify the configuration error = CommErr.Verify; byte[] config = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == ReadRequestPort(ihead, MessageID.Configuration, 0, ConfigStruct.Length, out config, cfg.CommTimeout)) { ihead.ConfigStruct = ConfigStruct.FromByteArray(config); if ((ihead.ConfigStruct.MeterState == MeterState.Test) && (ihead.ConfigStruct.TestModeConfig == testModeConfig)) { error = CommErr.None; resultStr = ihead.ConfigStruct.ToString(1); break; } } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } ClosePort(ihead); /// Close RFID port return error; } /// /// Set the watermeter to the active mode. /// Read a part of configuration afterwards to verify the mode was set correctly. /// /// iPERL head object /// String passed to caller /// true on success static CommErr SetActiveMode(int threadId, IperlHead ihead, ref string resultStr) { if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.CmdActive; /// Switch to active mode byte[] cmd = new byte[1] { (byte)Command.SetActiveMode }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Command, 0, 1, cmd, cfg.CommTimeout)) { error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } #if VERIFY_ACTIVE_MODE if (error == CommErr.None) { error = CommErr.Verify; /// Read configuration byte[] cfg_0_3 = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (ihead.ConfigStruct == null) { if (0 == ReadRequestPort(threadId, ihead, MessageID.Configuration, 0, 4, out cfg_0_3, cfg.CommTimeout)) { ihead.ConfigStruct.Update(0, cfg_0_3); if (ihead.ConfigStruct.MeterState == MeterState.Active) { error = CommErr.None; resultStr = ihead.ConfigStruct.ToString(1); break; } } } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } #else if (error == CommErr.None) { if (ihead.ConfigStruct == null) resultStr = "OK (Config not available)"; else resultStr = ihead.ConfigStruct.ToString(1); } #endif ClosePort(ihead); /// Close RFID port return error; } /// /// Read a complete calibration structure from the watermeter /// /// Water meter object /// String passed to caller /// true on success static CommErr ReadCalibration(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Read; int readRetVal = 0; /// Read calibration byte[] calib = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { readRetVal = ReadRequestPort(ihead, MessageID.Calibration, 0, CalibrationStruct.Length, out calib, cfg.CommTimeout); if (readRetVal == 0) { ihead.CalibrationStruct = CalibrationStruct.FromByteArray(calib); if (wm.OrigCalibFactor == 0) { wm.OrigCalibFactor = ihead.CalibrationStruct.Calibration; wm.FWVersion = ihead.CalibrationStruct.FWVersionStr(); } resultStr = ihead.CalibrationStruct.ToString(); error = ihead.VerifyIPerlType() ? CommErr.None : CommErr.WrongIPerlType; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } ClosePort(ihead); /// Close RFID port return error + Math.Max(0, Math.Min(readRetVal, 4)); } /// /// Read a complete calibration structure from the watermeter /// /// Water meter object /// String passed to caller /// true on success static CommErr ReadCalibrationV4(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Read; int readRetVal = 0; /// Read calibration byte[] calib = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { readRetVal = ReadRequestPort(ihead, MessageID.Calibration, 0, CalibrationStructV4.Length, out calib, cfg.CommTimeout); if (readRetVal == 0) { ihead.CalibrationStructV4 = CalibrationStructV4.FromByteArray(calib); if ((wm.OrigCalibFactor == 0) && (wm.OrigCalibFactorLNA == 0)) { wm.OrigCalibFactor = ihead.CalibrationStructV4.Calibration; wm.OrigCalibFactorLNA = ihead.CalibrationStructV4.CalibrationLNA; wm.FWVersion = ihead.CalibrationStructV4.FWVersionStr(); } resultStr = ihead.CalibrationStructV4.ToString(); error = ihead.VerifyIPerlType() ? CommErr.None : CommErr.WrongIPerlType; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } ClosePort(ihead); /// Close RFID port return error + Math.Max(0, Math.Min(readRetVal, 4)); } /// /// Write the calculated calibration factor to the water meter. /// Read a part of CalibrationStruct afterwards to verify factor was written correctly. /// /// Thread ID /// IperlHead object /// Water meter object /// String passed to caller /// true on success static CommErr WriteCalibrationFactor(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed || (ihead.CalibrationStruct == null)) return CommErr.CommFailed; /// /// Parse calibration factor (1 argument) or calibration factor limits (2 arguments) /// UInt16 newCalibFactor = 0; if (multiTestParams[currentActivityStep].Activity.Length > WriteCalibrationFactorStr.Length) { UInt16 factorLimitLo; UInt16 factorLimitHi; UInt16 val; string calibFactrorStr = multiTestParams[currentActivityStep].Activity.Substring(WriteCalibrationFactorStr.Length + 1); 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) { /// /// Lower and upper limits for the calibration factor are specified as iPerlCommunication activity arguments /// if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest; newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, factorLimitLo, factorLimitHi); } else if (arguments.Length == 1 && UInt16.TryParse(arguments[0], out val) && val > 0) { /// /// Calibration factor value is specified as an iPerlCommunication activity argument /// newCalibFactor = val; /// Update with specified value } else if (arguments.Length == 1 && wm.GetTestData(arguments[0]) != null) { /// /// Adjustment test name is specified as an iPerlCommunication activity argument /// 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; } } newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi); } else { /// /// Otherwise the last test is supposed to be an adjustment test /// if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest; newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi); } } else { /// /// No iPerlCommunication activity arguments --> The last test is supposed to be an adjustment test /// if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest; newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi); } if (newCalibFactor == 0) return CommErr.OutOfRange; /// /// Start communication with iPerl /// if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error; byte[] data = new byte[2] { (byte)(newCalibFactor & 0x00FF), (byte)((newCalibFactor >> 8) & 0x00FF) }; int writeAndVerifyRetries = 0; do { /// /// Write the new calibration factor (up to cfg.MaxCommRetries tims) /// error = CommErr.Write; if (0 == WriteRequestPort(ihead, MessageID.Calibration, 2, 2, data, cfg.CommTimeout)) { /// /// Read and verify the calibration factor /// error = CommErr.ReadAfterWrite; byte[] calib_2_3 = null; if (0 == ReadRequestPort(ihead, MessageID.Calibration, 2, 2, out calib_2_3, cfg.CommTimeout)) { 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; ihead.CalibrationStruct.Update(data, 2); wm.CalibFactor = newCalibFactor; resultStr = ihead.CalibrationStruct.ToString(); break; } } } ihead.CalibrationStruct.Update(data, 2); } while (++writeAndVerifyRetries <= cfg.MaxCommRetries); ClosePort(ihead); /// Close RFID port return error; } /// /// Write the calculated calibration factor to the water meter. /// Read a part of CalibrationStruct afterwards to verify factor was written correctly. /// /// Thread ID /// IperlHead object /// Water meter object /// String passed to caller /// true on success static CommErr WriteCalibrationV4Factors(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed || (ihead.CalibrationStructV4 == null)) return CommErr.CommFailed; /// /// Parse calibration factor (1 argument) or calibration factor limits (2 arguments) /// UInt16 newCalibFactor = 0; UInt16 newCalibFactorLNA = 0; if (multiTestParams[currentActivityStep].Activity.Length > WriteCalibrationV4FactorsStr.Length) { UInt16 factorLimitLo = 0; UInt16 factorLimitHi = 0; UInt16 lnaFactorLimitLo = 0; UInt16 lnaFactorLimitHi = 0; Results.Entities.TestData adjustTestData = null; Results.Entities.TestData lnaAdjustTestData = null; Results.Entities.MeterTestRslt adjustTestRslt = null; Results.Entities.MeterTestRslt lnaAdjustTestRslt = null; string calibFactrorStr = multiTestParams[currentActivityStep].Activity.Substring(WriteCalibrationV4FactorsStr.Length + 1); string[] arguments = calibFactrorStr.Split(new char[] { ' ' }); if (arguments.Length == 6) { if (!wm.TryGetTestData(arguments[0], out adjustTestData) || !UInt16.TryParse(arguments[1], out factorLimitLo) || factorLimitLo <= 0 && !UInt16.TryParse(arguments[2], out factorLimitHi) || factorLimitHi <= 0 && !wm.TryGetTestData(arguments[3], out lnaAdjustTestData) || !UInt16.TryParse(arguments[4], out lnaFactorLimitLo) || lnaFactorLimitLo <= 0 && !UInt16.TryParse(arguments[5], out lnaFactorLimitHi) || lnaFactorLimitHi <= 0) { return CommErr.WrongArguments; } else { adjustTestRslt = GetAverageTestRslt(wm, adjustTestData); lnaAdjustTestRslt = GetAverageTestRslt(wm, lnaAdjustTestData); if ((adjustTestRslt == null) || (lnaAdjustTestRslt == null)) { return CommErr.MissingTest; } newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibFactor, factorLimitLo, factorLimitHi); newCalibFactorLNA = ihead.CalculateNewCalibFactor(lnaAdjustTestRslt, ihead.CalibFactorLNA, lnaFactorLimitLo, lnaFactorLimitHi); } } else if (arguments.Length == 4) { if (!wm.TryGetTestData(arguments[0], out adjustTestData) || !wm.TryGetTestData(arguments[1], out lnaAdjustTestData) || !UInt16.TryParse(arguments[2], out lnaFactorLimitLo) || lnaFactorLimitLo <= 0 && !UInt16.TryParse(arguments[3], out lnaFactorLimitHi) || lnaFactorLimitHi <= 0) { return CommErr.WrongArguments; } else { factorLimitLo = ihead.FactorLimitLo; factorLimitHi = ihead.FactorLimitHi; adjustTestRslt = GetAverageTestRslt(wm, adjustTestData); lnaAdjustTestRslt = GetAverageTestRslt(wm, lnaAdjustTestData); if ((adjustTestRslt == null) || (lnaAdjustTestRslt == null)) { return CommErr.MissingTest; } newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibFactor, factorLimitLo, factorLimitHi); newCalibFactorLNA = ihead.CalculateNewCalibFactor(lnaAdjustTestRslt, ihead.CalibFactorLNA, lnaFactorLimitLo, lnaFactorLimitHi); } } else if (arguments.Length == 2) { if (!wm.TryGetTestData(arguments[0], out adjustTestData) || !wm.TryGetTestData(arguments[1], out lnaAdjustTestData)) { return CommErr.WrongArguments; } else { factorLimitLo = ihead.FactorLimitLo; factorLimitHi = ihead.FactorLimitHi; lnaFactorLimitLo = ihead.FactorLimitLo; lnaFactorLimitHi = ihead.FactorLimitHi; adjustTestRslt = GetAverageTestRslt(wm, adjustTestData); lnaAdjustTestRslt = GetAverageTestRslt(wm, lnaAdjustTestData); if ((adjustTestRslt == null) || (lnaAdjustTestRslt == null)) { return CommErr.MissingTest; } newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibFactor, factorLimitLo, factorLimitHi); newCalibFactorLNA = ihead.CalculateNewCalibFactor(lnaAdjustTestRslt, ihead.CalibFactorLNA, lnaFactorLimitLo, lnaFactorLimitHi); } } else { return CommErr.WrongArguments; } } else { return CommErr.WrongArguments; } if (newCalibFactor == 0 || newCalibFactorLNA == 0) return CommErr.OutOfRange; /// /// Start communication with iPerl /// if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error; byte[] data = new byte[2] { (byte)(newCalibFactor & 0x00FF), (byte)((newCalibFactor >> 8) & 0x00FF) }; byte[] dataLNA = new byte[2] { (byte)(newCalibFactorLNA & 0x00FF), (byte)((newCalibFactorLNA >> 8) & 0x00FF) }; int writeAndVerifyRetries = 0; do { /// /// Write the new calibration factor (up to cfg.MaxCommRetries tims) /// error = CommErr.Write; if (0 == WriteRequestPort(ihead, MessageID.Calibration, 2, 2, data, cfg.CommTimeout) && 0 == WriteRequestPort(ihead, MessageID.Calibration, 34, 2, dataLNA, cfg.CommTimeout)) { /// /// Read and verify the calibration factor /// error = CommErr.ReadAfterWrite; byte[] calib_2_3 = null; byte[] calib_34_35 = null; if (0 == ReadRequestPort(ihead, MessageID.Calibration, 2, 2, out calib_2_3, cfg.CommTimeout) && 0 == ReadRequestPort(ihead, MessageID.Calibration, 34, 2, out calib_34_35, cfg.CommTimeout)) { 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] && calib_34_35 != null && calib_34_35.Length == 2 && dataLNA[0] == calib_34_35[0] && dataLNA[1] == calib_34_35[1]) { error = CommErr.None; ihead.CalibrationStructV4.Update(data, 2); ihead.CalibrationStructV4.Update(dataLNA, 34); wm.CalibFactor = newCalibFactor; wm.CalibFactorLNA = newCalibFactorLNA; resultStr = ihead.CalibrationStructV4.ToString(); break; } } } ihead.CalibrationStructV4.Update(data, 2); ihead.CalibrationStructV4.Update(dataLNA, 34); writeAndVerifyRetries++; if ((writeAndVerifyRetries <= cfg.MaxCommRetries) && (cfg.DelayBetweenRetries > 0)) { /// Delay between retries Thread.Sleep(cfg.DelayBetweenRetries); } } while (writeAndVerifyRetries <= cfg.MaxCommRetries); ClosePort(ihead); /// Close RFID port return error; } /// /// Get averaged meter test result using test name and repetitions from a given test data. /// /// Water meter /// TestData (name and repetitions) /// (1) selected MeterTestRslt or (2) average of repeated MTR-s or (3) null when at least one MTR is missing static Results.Entities.MeterTestRslt GetAverageTestRslt(Results.Entities.WaterMeter wm, Results.Entities.TestData testData) { Results.Entities.MeterTestRslt avgTestRslt; if (testData.Repeats > 1) { /// Calculate a summarized test result if Repeats > 1 avgTestRslt = new Results.Entities.MeterTestRslt(); for (int i = 1; i <= testData.Repeats; i++) { Results.Entities.MeterTestRslt oneMTR = wm.GetMeterTestRslt(Utils.TestTitle(testData, i)); if (oneMTR == null || !oneMTR.TestDone) return null; avgTestRslt.VolumeMeter += oneMTR.VolumeMeter; avgTestRslt.VolumeRef += oneMTR.VolumeRef; } } else { avgTestRslt = wm.GetMeterTestRslt(Utils.TestTitle(testData, 1)); if (avgTestRslt == null || !avgTestRslt.TestDone) return null; } return avgTestRslt; } /// /// Normalize calibration factor in case ti is close to value 8000. /// /// Water meter object /// String passed to caller /// true on success static CommErr NormalizeCalibrationFactor(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed || (ihead.CalibrationStruct == null)) return CommErr.CommFailed; if (ihead.FactorLimitLo <= ihead.CalibFactor && ihead.CalibFactor <= ihead.FactorLimitHi) { resultStr = "Calibratin factor is OK"; return CommErr.None; /// No need to update the calibration factor } if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; /// Determine the new calibration factor UInt16 defaultCalibFactor; switch (ihead.CalibrationStruct.MeterType) { case MeterType.DN15: defaultCalibFactor = 2710; break; case MeterType.DN20: defaultCalibFactor = 3746; break; case MeterType.DN25: defaultCalibFactor = 3300; break; case MeterType.DN32: defaultCalibFactor = 2500; break; case MeterType.DN40: defaultCalibFactor = 3080; break; case MeterType.DN25_Q3_10: case MeterType.CoaxManifold: default: defaultCalibFactor = 3040; break; } byte[] data = new byte[2] { (byte)(defaultCalibFactor & 0x00FF), (byte)((defaultCalibFactor >> 8) & 0x00FF) }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Calibration, 2, 2, data, cfg.CommTimeout)) { error = CommErr.None; ihead.CalibrationStruct.Update(data, 2); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if (error == CommErr.None) { error = CommErr.Verify; /// Read calibration byte[] calib_2_3 = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == ReadRequestPort(ihead, MessageID.Calibration, 2, 2, out calib_2_3, cfg.CommTimeout)) { error = CommErr.None; ihead.CalibrationStruct.Update(calib_2_3, 2); resultStr = ihead.CalibrationStruct.ToString(); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } ClosePort(ihead); /// Close RFID port return error; } /// /// Normalize calibration factor in case ti is close to value 8000. /// /// Water meter object /// String passed to caller /// true on success static CommErr NormalizeCalibrationV4Factors(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed || (ihead.CalibrationStructV4 == null)) return CommErr.CommFailed; if (ihead.FactorLimitLo <= ihead.CalibFactor && ihead.CalibFactor <= ihead.FactorLimitHi) { resultStr = "Calibratin factor is OK"; return CommErr.None; /// No need to update the calibration factor } if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; /// Determine the new calibration factor UInt16 defaultCalibFactor; switch (ihead.CalibrationStructV4.MeterType) { case MeterType.DN15: defaultCalibFactor = 2710; break; case MeterType.DN20: defaultCalibFactor = 3746; break; case MeterType.DN25: defaultCalibFactor = 3300; break; case MeterType.DN32: defaultCalibFactor = 2500; break; case MeterType.DN40: defaultCalibFactor = 3080; break; case MeterType.DN25_Q3_10: case MeterType.CoaxManifold: default: defaultCalibFactor = 3040; break; } byte[] data = new byte[2] { (byte)(defaultCalibFactor & 0x00FF), (byte)((defaultCalibFactor >> 8) & 0x00FF) }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.Calibration, 2, 2, data, cfg.CommTimeout)) { error = CommErr.None; ihead.CalibrationStructV4.Update(data, 2); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if (error == CommErr.None) { error = CommErr.Verify; /// Read calibration byte[] calib_2_3 = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == ReadRequestPort(ihead, MessageID.Calibration, 2, 2, out calib_2_3, cfg.CommTimeout)) { error = CommErr.None; ihead.CalibrationStructV4.Update(calib_2_3, 2); resultStr = ihead.CalibrationStructV4.ToString(); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } ClosePort(ihead); /// Close RFID port return error; } /// /// Reset both Q2 correction factors in the memory to 0. /// Read them back to verify factors were written correctly. /// /// Water meter object /// String passed to caller /// true on success static CommErr ReadQ2Correction(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Read; /// Write zero Q2 correction byte[] rdData = null; /// for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == ReadRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, out rdData, cfg.CommTimeout)) { error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if ((error == CommErr.None) && (rdData != null) && (rdData.Length == 2)) { resultStr = "Q2 corrections successfully read"; wm.Q2CorrLR = ihead.Q2CorrLR = (int)((SByte)rdData[0]); wm.Q2CorrRL = ihead.Q2CorrRL = (int)((SByte)rdData[1]); } ClosePort(ihead); /// Close RFID port return error; } /// /// Reset both Q2 correction factors to 0. /// Read them back to verify factors were written correctly. /// /// Water meter object /// String passed to caller /// true on success static CommErr ResetQ2Correction(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { return WriteQ2Corrections(threadId, ihead, wm, ref resultStr, 0, 0); } /// /// Set both Q2 correction factors to default values obtained by a REST service /// Read them back to verify factors were written correctly. /// /// Water meter object /// String passed to caller /// true on success static CommErr WriteDefaultQ2Corrections(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (ProcessData.IsQ2PreCorrectionCalculated) { return WriteQ2Corrections(threadId, ihead, wm, ref resultStr, ProcessData.CalculatedQ2PreCorrectionLR, ProcessData.CalculatedQ2PreCorrectionRL); } else { int q2corrRL; int q2corrLR; switch (ihead.MeterType) { case MeterType.DN15: q2corrRL = cfg.DfltQ2c_15_rl; q2corrLR = cfg.DfltQ2c_15_lr; break; case MeterType.DN20: q2corrRL = cfg.DfltQ2c_20_rl; q2corrLR = cfg.DfltQ2c_20_lr; break; case MeterType.DN25: q2corrRL = cfg.DfltQ2c_25_63_rl; q2corrLR = cfg.DfltQ2c_25_63_lr; break; case MeterType.DN25_Q3_10: q2corrRL = cfg.DfltQ2c_25_10_rl; q2corrLR = cfg.DfltQ2c_25_10_lr; break; case MeterType.DN32: q2corrRL = cfg.DfltQ2c_32_rl; q2corrLR = cfg.DfltQ2c_32_lr; break; case MeterType.DN40: q2corrRL = cfg.DfltQ2c_40_rl; q2corrLR = cfg.DfltQ2c_40_lr; break; default: q2corrRL = 0; q2corrLR = 0; break; } return WriteQ2Corrections(threadId, ihead, wm, ref resultStr, q2corrLR, q2corrRL); } } /// /// Write both Q2 correction factors to given values. /// Read them back to verify factors were written correctly. /// /// Water meter object /// String passed to caller /// true on success static CommErr WriteQ2Corrections(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr, int factorLR, int factorRL) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; /// Write zero Q2 correction byte[] wrData = new byte[2] { (byte)factorLR, (byte)factorRL }; /// for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, wrData.Length, wrData, cfg.CommTimeout)) { wm.Q2CorrRL = ihead.Q2CorrRL = factorRL; wm.Q2CorrLR = ihead.Q2CorrLR = factorLR; error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// /// Verification disabled on 16.02.2016 /// #if VERIFY_Q2_CORR_RESET /// Verify the correction factors if (error == CommErr.None) { error = CommErr.Verify; /// Read calibration byte[] rdData = null; for (int j = 0; j < cfg.MaxCommRetries; j++) { if ((0 == ReadRequestPort(threadId, ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, out rdData, cfg.CommTimeout)) && (rdData != null) && (rdData.Length == 2) && (rdData[0] == 0) && (rdData[1] == 0)) { error = CommErr.None; resultStr = string.Format("Q2 correction set to LR={0}, RL={1}", factorLR, factorRL); break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } #else if (error == CommErr.None) { resultStr = string.Format("Q2 correction set to LR={0}, RL={1}", factorLR, factorRL); } #endif ClosePort(ihead); /// Close RFID port return error; } static CommErr InitOrReadQ2Corrections(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (wm.Pruefindex == 0) return CommErr.CommFailed; /// Unknown pruefindex if (wm.Pruefindex == 1) { int q2corrRL; int q2corrLR; if (ProcessData.IsQ2PreCorrectionCalculated) { q2corrRL = ProcessData.CalculatedQ2PreCorrectionRL; q2corrLR = ProcessData.CalculatedQ2PreCorrectionLR; } else { switch (ihead.MeterType) { case MeterType.DN15: q2corrRL = cfg.DfltQ2c_15_rl; q2corrLR = cfg.DfltQ2c_15_lr; break; case MeterType.DN20: q2corrRL = cfg.DfltQ2c_20_rl; q2corrLR = cfg.DfltQ2c_20_lr; break; case MeterType.DN25: q2corrRL = cfg.DfltQ2c_25_63_rl; q2corrLR = cfg.DfltQ2c_25_63_lr; break; case MeterType.DN25_Q3_10: q2corrRL = cfg.DfltQ2c_25_10_rl; q2corrLR = cfg.DfltQ2c_25_10_lr; break; case MeterType.DN32: q2corrRL = cfg.DfltQ2c_32_rl; q2corrLR = cfg.DfltQ2c_32_lr; break; case MeterType.DN40: q2corrRL = cfg.DfltQ2c_40_rl; q2corrLR = cfg.DfltQ2c_40_lr; break; default: q2corrRL = 0; q2corrLR = 0; break; } } return WriteQ2Corrections(threadId, ihead, wm, ref resultStr, q2corrLR, q2corrRL); } else { return ReadQ2Correction(threadId, ihead, wm, ref resultStr); } } /// /// Reset 2Hz correction factor in the memory to 0. /// /// Water meter object /// String passed to caller /// true on success static CommErr Reset2HzCorrection(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; /// Write zero Q2 correction byte[] wrData = new byte[1] { 0 }; /// for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, wrData.Length, wrData, cfg.CommTimeout)) { error = CommErr.None; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// /// 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++) { if ((0 == ReadRequestPort(threadId, ihead, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, 1, out rdData, cfg.CommTimeout)) && (rdData != null) && (rdData.Length == 2) && (rdData[0] == 0) && (rdData[1] == 0)) { error = CommErr.None; resultStr = "2Hz correction reset to 0"; ihead.Q2CorrectionFactor = 0; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } #else if (error == CommErr.None) { resultStr = "2Hz correction reset to 0"; ihead.Hz2Correction = 0; } #endif ClosePort(ihead); /// Close RFID port return error; } /// /// Write the calculated Q2 correction factors to the memory. /// Read them back to verify factors were written correctly. /// /// Write Q2 correction /// Write Q2 correction Alt /// Write Q2 correction [Greece | R-L | L-R] testname /// Update Q2 corrections /// Conditional update of Q2 corrections /// /// Water meter object /// String passed to caller /// true on success static CommErr CalculateAndWriteQ2Corrections(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, Test test, ref string resultStr, Q2CorrType q2CorrType, string restOfLine) { var args = string.IsNullOrEmpty(restOfLine) ? new string[0] : restOfLine.Split(new char[] { ' ' }); Results.Entities.MeterTestRslt q2adjResult; /// The only test or the 1st test (the test in R-L direction) Results.Entities.TestData q2adjTestData; /// if (args.Length == 0) { /// In case of no test name argument, ihead.LastTestResult is used (if it exists) if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest; q2adjResult = ihead.LastTestResult; q2adjTestData = q2adjResult.TestRslt.TestData; } else // if (args.Length >= 1) { /// Get test data from (the 1st) test name q2adjTestData = wm.GetTestData(args[0]); if (q2adjTestData == null) return CommErr.MissingTest; if (q2adjTestData.Repeats == 1) { /// Find a test result if Repets == 1 q2adjResult = wm.GetMeterTestRslt(args[0]); 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})", args[0], i, q2adjTestData.Repeats)); if (oneMTR == null || !oneMTR.TestDone) return CommErr.MissingTest; q2adjResult.VolumeMeter += oneMTR.VolumeMeter; q2adjResult.VolumeRef += oneMTR.VolumeRef; if (i == 1) { q2adjResult.CalibFactor = oneMTR.CalibFactor; q2adjResult.CalibFactorLNA = oneMTR.CalibFactorLNA; q2adjResult.Q2CorrRL = oneMTR.Q2CorrRL; q2adjResult.Q2CorrLR = oneMTR.Q2CorrLR; } } q2adjResult.Error = Config.Formulas.ErrorFromVolumes(q2adjResult.VolumeMeter, q2adjResult.VolumeRef); } } Results.Entities.MeterTestRslt q2adjResult2 = null; /// 2nd test name for a test in L-R direction Results.Entities.TestData q2adjTestData2 = null; /// if (args.Length >= 2) { /// Get the 2nd test data from the 2nd test name q2adjTestData2 = wm.GetTestData(args[1]); if (q2adjTestData2 == null) return CommErr.MissingTest; if (q2adjTestData2.Repeats == 1) { /// Find a test result if Repets == 1 q2adjResult2 = wm.GetMeterTestRslt(args[1]); if (q2adjResult2 == null || !q2adjResult2.TestDone) return CommErr.MissingTest; } else { /// Calculate a summarized test result if Repeats > 1 q2adjResult2 = new Results.Entities.MeterTestRslt(); for (int i = 1; i <= q2adjTestData2.Repeats; i++) { Results.Entities.MeterTestRslt oneMTR = wm.GetMeterTestRslt(string.Format("{0} ({1}/{2})", args[1], i, q2adjTestData2.Repeats)); if (oneMTR == null || !oneMTR.TestDone) return CommErr.MissingTest; q2adjResult2.VolumeMeter += oneMTR.VolumeMeter; q2adjResult2.VolumeRef += oneMTR.VolumeRef; if (i == 1) { q2adjResult2.CalibFactor = oneMTR.CalibFactor; q2adjResult2.CalibFactorLNA = oneMTR.CalibFactorLNA; q2adjResult2.Q2CorrRL = oneMTR.Q2CorrRL; q2adjResult2.Q2CorrLR = oneMTR.Q2CorrLR; } } q2adjResult2.Error = Config.Formulas.ErrorFromVolumes(q2adjResult2.VolumeMeter, q2adjResult2.VolumeRef); } } if (q2adjResult == null || ((q2CorrType == Q2CorrType.Update || q2CorrType == Q2CorrType.ConditionalUpdate) && q2adjResult2 == null)) { return CommErr.MissingTest; /// Procedure configuration error } if ((q2CorrType == Q2CorrType.ConditionalUpdate || q2CorrType == Q2CorrType.ConditionalUpdateRL || q2CorrType == Q2CorrType.ConditionalUpdateLR) && wm.PassedFromTests()) { resultStr = string.Format("No Q2 correction update"); rfidDataLogger.InfoFormat("{0}({1}): No Q2 correction update", ihead.Name, ihead.SerialNr); return CommErr.None; /// No Q2 correction when doing conditional update and WM passed } double errLimitLo = test.ErrLimLo + test.Uncertainty; double errLimitHi = test.ErrLimHi - test.Uncertainty; /// if (q2adjResult.Error < errLimitLo || errLimitHi < q2adjResult.Error || (q2adjResult2 != null && (q2adjResult2.Error < errLimitLo || errLimitHi < q2adjResult2.Error))) { /// At least one of Q2 errors is out of range for Q2 correction log.WarnFormat("OoR => no Q2 correction: Pos={0}, PCB#={1}, ***Q2_RL err={2}%***, ***Q2_LR err={3}%***, CalTarget={4}%, [Lo={5}%, Hi={6}%]", ihead.Name, ihead.SerialNr, q2adjResult.Error.ToString("F2"), q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty, ihead.CalibTargetQ2.ToString("F1"), errLimitLo.ToString("F2"), errLimitHi.ToString("F2")); resultStr = string.Format("Q2 error is out of range => no Q2 correction"); rfidDataLogger.InfoFormat("{0}({1}): Q2 error ({2},{3}) is out of range ({4}..{5}) => Failed", ihead.Name, ihead.SerialNr, q2adjResult.Error.ToString("F2"), q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty, errLimitLo.ToString("F2"), errLimitHi.ToString("F2")); return CommErr.Q2OutOfRange; } /// /// Calculate Q2 correction factor(s) from an error measured at Q2 /// double q2Correction = 0; double q2Correction2 = 0; /// L-R direction in case of Q2CorrType.Update and Q2CorrType.ConditionalUpdate if (q2CorrType == Q2CorrType.Update || q2CorrType == Q2CorrType.ConditionalUpdate) { /// Calculate two Q2 correction factors from two tests done in both directions q2Correction = ihead.CalculateQ2CorrectionFactor(q2adjResult, ihead.CalibTargetQ2, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL); q2Correction2 = ihead.CalculateQ2CorrectionFactor(q2adjResult2, ihead.CalibTargetQ2, q2adjTestData2.Qfrom, q2adjResult2.Q2CorrLR); } else { /// Calculate Q2 correction factors from a single test q2Correction = ihead.CalculateQ2CorrectionFactor(q2adjResult, ihead.CalibTargetQ2, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL); q2Correction2 = ihead.CalculateQ2CorrectionFactor(q2adjResult, ihead.CalibTargetQ2, q2adjTestData.Qfrom, q2adjResult.Q2CorrLR); } int q2CorrRL = 0; int q2CorrLR = 0; /// if (q2CorrType == Q2CorrType.Standard || q2CorrType == Q2CorrType.Standard_incl_05 || q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestRLDir) { /// /// Standard process /// if (q2CorrType == Q2CorrType.Standard && Math.Abs(q2adjResult.Error - ihead.CalibTargetQ2) <= 0.5) { resultStr = string.Format("Q2 correction = 0 (writing bypassed)"); return CommErr.None; } q2CorrRL = (int)Math.Round(1.1 * q2Correction); q2CorrLR = (int)Math.Round(0.5 * q2Correction); } else if (q2CorrType == Q2CorrType.Dewa || q2CorrType == Q2CorrType.Dewa_incl_05) { /// /// Process for DEWA /// if (q2CorrType == Q2CorrType.Dewa && Math.Abs(q2adjResult.Error - ihead.CalibTargetQ2) <= 0.5) { resultStr = string.Format("Q2 correction = 0 (writing bypassed)"); return CommErr.None; } /// Use the same correction factor in both directions q2CorrRL = (int)Math.Round(1.0 * q2Correction2); q2CorrLR = (int)Math.Round(1.0 * q2Correction2); } else if (q2CorrType == Q2CorrType.Greece || q2CorrType == Q2CorrType.Greece_incl_05 || q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestLRDir) { /// /// Process for Greece /// if (q2CorrType == Q2CorrType.Greece && Math.Abs(q2adjResult.Error - ihead.CalibTargetQ2) <= 0.5) { resultStr = string.Format("Q2 correction = 0 (writing bypassed)"); return CommErr.None; } q2CorrRL = (int)Math.Round(2.0 * q2Correction2); q2CorrLR = (int)Math.Round(1.0 * q2Correction2); } else if (q2CorrType == Q2CorrType.RL || q2CorrType == Q2CorrType.RL_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateRL) /// RL only { if (q2CorrType == Q2CorrType.RL && Math.Abs(q2adjResult.Error - ihead.CalibTargetQ2) <= 0.5) { resultStr = string.Format("Q2 correction = 0 (writing bypassed)"); return CommErr.None; } q2CorrRL = (int)Math.Round(q2Correction); } else if (q2CorrType == Q2CorrType.LR || q2CorrType == Q2CorrType.LR_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateLR) /// LR only { if (q2CorrType == Q2CorrType.LR && Math.Abs(q2adjResult.Error - ihead.CalibTargetQ2) <= 0.5) { resultStr = string.Format("Q2 correction = 0 (writing bypassed)"); return CommErr.None; } q2CorrLR = (int)Math.Round(q2Correction2); } else if ((q2CorrType == Q2CorrType.Update) || (q2CorrType == Q2CorrType.ConditionalUpdate)) { q2CorrRL = (int)Math.Round(q2Correction); q2CorrLR = (int)Math.Round(q2Correction2); } /// /// Write calculated Q2 correction factors into the water meter /// if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; if (q2CorrType == Q2CorrType.RL || q2CorrType == Q2CorrType.RL_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateRL) { /// /// Write R-L Q2 correction factor only /// byte[] wrData = new byte[1] { (byte)q2CorrRL }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddrRL, wrData.Length, wrData, cfg.CommTimeout)) { error = CommErr.None; wm.Q2CorrRL = ihead.Q2CorrRL = q2CorrRL; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } else if (q2CorrType == Q2CorrType.LR || q2CorrType == Q2CorrType.LR_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateLR) { /// /// Write L-R Q2 correction factor only /// byte[] wrData = new byte[1] { (byte)q2CorrLR }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddrLR, wrData.Length, wrData, cfg.CommTimeout)) { error = CommErr.None; wm.Q2CorrLR = ihead.Q2CorrLR = q2CorrLR; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } else { /// /// Write both Q2 correction factors /// byte[] wrData = new byte[2] { (byte)q2CorrLR, (byte)q2CorrRL }; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, wrData.Length, wrData, cfg.CommTimeout)) { error = CommErr.None; wm.Q2CorrRL = ihead.Q2CorrRL = q2CorrRL; wm.Q2CorrLR = ihead.Q2CorrLR = q2CorrLR; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } /// /// 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++) { if ((0 == ReadRequestPort(threadId, ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, 2, out rdData, cfg.CommTimeout)) && (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); rfidDataLogger.Warn(ihead.Name + ": " + resultStr); wm.Q2ErrWOCorrection = ihead.Q2ErrorWOCorrection; if (q2CorrType != Q2CorrType.LR) wm.Q2CorrRFlow = ihead.Q2CorrRFlow = (int)(sbyte)q2CorrRFlow; if (q2CorrType != Q2CorrType.RL) wm.Q2CorrLFlow = ihead.Q2CorrLFlow = (int)(sbyte)q2CorrLFlow; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } #else /// /// Update WaterMeter entity and IperlHead /// if (error == CommErr.None) { if (q2CorrType == Q2CorrType.RL) { resultStr = string.Format("Q2 correction: RL={0}", q2CorrRL); } else if (q2CorrType == Q2CorrType.LR) { resultStr = string.Format("Q2 correction: LR={0}", q2CorrLR); } else { resultStr = string.Format("Q2 correction: RL={0}, LR={1}", q2CorrRL, q2CorrLR); } rfidDataLogger.WarnFormat("{0}: {1}", ihead.Name, resultStr); if ((q2CorrType != Q2CorrType.Update) && (q2CorrType != Q2CorrType.ConditionalUpdate)) { wm.Q2ErrWOCorrection = ihead.Q2ErrWOCorrection = q2adjResult.Error; } } #endif ClosePort(ihead); /// Close RFID port return error; } /// /// Write the calculated 2Hz correction factor to the memory. /// /// Water meter object /// String passed to caller /// true on success static CommErr Write2HzCorrection(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; /// Calculate the correction ihead.Hz2CorrectionDone = false; int hz2CorrectionFactor; bool wmOK = ihead.Calculate2HzCorrectionFactor(ihead.LastTestResult2, ihead.LastTestResult, out ihead.Diff2Hz8Hz, out hz2CorrectionFactor); if (hz2CorrectionFactor == 0) { resultStr = string.Format("2Hz correction = 0 (writing bypassed)"); return CommErr.None; } if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port CommErr error = CommErr.Write; Byte hz2CorrectionByte = (byte)(hz2CorrectionFactor & 0x000000FF); byte[] wrData = new byte[1] { hz2CorrectionByte }; /// for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, wrData.Length, wrData, cfg.CommTimeout)) { error = CommErr.None; wm.Hz2Correction = ihead.Hz2Correction = hz2CorrectionFactor; wm.Hz2CorrectionDone = ihead.Hz2CorrectionDone = true; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } /// /// 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++) { 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); rfidDataLogger.Warn(ihead.Name + ": " + resultStr); wm.Hz2Correction = ihead.Hz2CorrectionFactor = hz2CorrectionFactor; wm.Diff2Hz8Hz = ihead.Diff2Hz8Hz; wm.Hz2CorrectionDone = ihead.Hz2CorrectionDone; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } } #else if (error == CommErr.None) { resultStr = string.Format("2Hz correction = {0}", (SByte)hz2CorrectionByte); rfidDataLogger.Warn(ihead.Name + ": " + resultStr); wm.Diff2Hz8Hz = ihead.Diff2Hz8Hz; wm.Hz2CorrectionDone = ihead.Hz2CorrectionDone = true; wm.Hz2Correction = ihead.Hz2Correction = hz2CorrectionFactor; } #endif ClosePort(ihead); /// Close RFID port return error; } /// /// DEWA rework. /// /// iPERL head object /// Water meter object /// Arrow direction /// String passed to caller /// true on success static CommErr DewaRework(IperlHead ihead, Results.Entities.WaterMeter wm, FlowDir flowDir, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port byte arrow = (flowDir == FlowDir.L_R) ? (byte)1 : (byte)2; /// L-R is reverse flow (=1), R-L is forward flow (=2)(default) iPerlDataWrite[] dataToBeWritten = new iPerlDataWrite[] { new iPerlDataWrite(MessageID.MetrologyMemory, 0x19A1, new byte[] { (byte)0xA5 }, "Open Sealing"), new iPerlDataWrite(MessageID.RadioPassthrough, 0x1804, new byte[] { (byte)1 }, "System Status"), new iPerlDataWrite(MessageID.MetrologyMemory, 0x1985, new byte[] { arrow }, "Arrow"), new iPerlDataWrite(MessageID.MetrologyMemory, 0x199C, new byte[5], "Clear S/N"), new iPerlDataWrite(MessageID.Command, 0x0000, new byte[] { (byte)Command.SetActiveMode }, "Set active mode"), new iPerlDataWrite(MessageID.Configuration, 0x0015, new byte[] { (byte)0xA0 }, "Test mode config = A0"), new iPerlDataWrite(MessageID.MetrologyMemory, 0x198E, new byte[] { (byte)(2510 & 0xFF), (byte)((2510 >> 8) & 0xFF) }, "Receipt mean current"), new iPerlDataWrite(MessageID.RadioPassthrough, 0x18A2, new byte[] { (byte)0x4A, (byte)0x53, (byte)0x3B, (byte)0x8F, (byte)0x70, (byte)0x31, (byte)0xC2, (byte)0x5D, (byte)0x6F, (byte)0x2D, (byte)0xE8, (byte)0x07, (byte)0x6E, (byte)0x0F, (byte)0x97, (byte)0xC3, }, "AES Key Crypted"), }; int successfyllyWrittenFlags = 0; /// Ones in this word represent communication failures, LSB represents the first step int mask = 1; foreach (var wData in dataToBeWritten) { bool isSuccessfullyWritten = false; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, wData.MessageID, wData.Offset, wData.Data.Length, wData.Data, cfg.CommTimeout)) { isSuccessfullyWritten = true; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if (!isSuccessfullyWritten) { /// Communication failed in this step successfyllyWrittenFlags = (successfyllyWrittenFlags | mask); } mask = (mask << 1); /// Adjust the mask for the next step } ClosePort(ihead); /// Close RFID port if (successfyllyWrittenFlags == 0) { /// Success if (ihead.ConfigStruct != null) { ihead.ConfigStruct.MeterState = MeterState.Active; ihead.ConfigStruct.TestModeConfig = (byte)0xA0; } resultStr = "OK"; return CommErr.None; } else { return CommErr.Write; } } /// /// Start testing a sealed meter /// /// iPERL head object /// Water meter object /// String passed to caller /// true on success static CommErr StartTestingSealedMeter(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port Byte testModeConfig = 0xA0; /// Default value /// if (multiTestParams[currentActivityStep].Activity.Length > StartTestingSealedMetersStr.Length) { string testModeConfigStr = multiTestParams[currentActivityStep].Activity.Substring(StartTestingSealedMetersStr.Length + 1); UInt16 byteVal; if (UInt16.TryParse(testModeConfigStr, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byteVal) && byteVal <= 255) { testModeConfig = (Byte)byteVal; /// Update with specified value } } iPerlDataWrite[] dataToBeWritten = new iPerlDataWrite[] { new iPerlDataWrite(MessageID.MetrologyMemory, 0x19A1, new byte[] { (byte)0xA5 }, "Open Sealing"), /// 0x5A=sealed, 0xA5=unsealed new iPerlDataWrite(MessageID.RadioPassthrough, 0x1804, new byte[] { (byte)1 }, "System Status"), new iPerlDataWrite(MessageID.Command, 0x0000, new byte[] { (byte)Command.SetActiveMode }, "Set active mode"), new iPerlDataWrite(MessageID.Configuration, 0x0015, new byte[] { testModeConfig }, string.Format("Test mode config = {0:X2}", testModeConfig)), }; if (ihead.ConfigStruct != null) ihead.OrigTestModeConfig = ihead.ConfigStruct.TestModeConfig; int successfyllyWrittenFlags = 0; /// Ones in this word represent communication failures, LSB represents the first step int mask = 1; foreach (var wData in dataToBeWritten) { bool isSuccessfullyWritten = false; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, wData.MessageID, wData.Offset, wData.Data.Length, wData.Data, cfg.CommTimeout)) { isSuccessfullyWritten = true; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if (!isSuccessfullyWritten) { /// Communication failed in this step successfyllyWrittenFlags = (successfyllyWrittenFlags | mask); } mask = (mask << 1); /// Adjust the mask for the next step } ClosePort(ihead); /// Close RFID port if (successfyllyWrittenFlags == 0) { /// Success if (ihead.ConfigStruct != null) { ihead.ConfigStruct.MeterState = MeterState.Active; ihead.ConfigStruct.TestModeConfig = (byte)0xA0; } resultStr = "OK"; return CommErr.None; } else { return CommErr.Write; } } /// /// End testing a sealed meter /// /// iPERL head object /// Water meter object /// String passed to caller /// true on success static CommErr EndTestingSealedMeter(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (ihead.CommFailed) return CommErr.CommFailed; if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port Byte testModeConfig = (ihead.OrigTestModeConfig != 0) ? ihead.OrigTestModeConfig : (byte)0x80; /// Restore original value (default is 0x80) iPerlDataWrite[] dataToBeWritten = new iPerlDataWrite[] { new iPerlDataWrite(MessageID.Command, 0x0000, new byte[] { (byte)Command.SetActiveMode }, "Set active mode"), new iPerlDataWrite(MessageID.Configuration, 0x0015, new byte[] { testModeConfig }, string.Format("Test mode config = {0:X2}", testModeConfig)), new iPerlDataWrite(MessageID.RadioPassthrough, 0x1804, new byte[] { (byte)0 }, "System Status"), new iPerlDataWrite(MessageID.MetrologyMemory, 0x19A1, new byte[] { (byte)0x5A }, "Close Sealing"), }; int successfyllyWrittenFlags = 0; /// Ones in this word represent communication failures, LSB represents the first step int mask = 1; foreach (var wData in dataToBeWritten) { bool isSuccessfullyWritten = false; for (int j = 0; j < cfg.MaxCommRetries; j++) { if (0 == WriteRequestPort(ihead, wData.MessageID, wData.Offset, wData.Data.Length, wData.Data, cfg.CommTimeout)) { isSuccessfullyWritten = true; break; } /// Delay between retries if (cfg.DelayBetweenRetries > 0) Thread.Sleep(cfg.DelayBetweenRetries); } if (!isSuccessfullyWritten) { /// Communication failed in this step successfyllyWrittenFlags = (successfyllyWrittenFlags | mask); } mask = (mask << 1); /// Adjust the mask for the next step } ClosePort(ihead); /// Close RFID port if (successfyllyWrittenFlags == 0) { /// Success if (ihead.ConfigStruct != null) { ihead.ConfigStruct.MeterState = MeterState.Active; ihead.ConfigStruct.TestModeConfig = (byte)0xA0; } resultStr = "OK"; return CommErr.None; } else { return CommErr.Write; } } static CommErr GetQ2PreCorrectionsFormRest(int threadId, IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr) { if (!ProcessData.IsQ2PreCorrectionCalculated) { ProcessData.IsQ2PreCorrectionCalculated = true; commonWMType = ihead.WMType_ID; bool success = iPerlCommunicationSeq.GetQ2PreCorrectionsOrBackups(cfg, commonWMType, out ProcessData.CalculatedQ2PreCorrectionLR, out ProcessData.CalculatedQ2PreCorrectionRL); } else if (ihead.WMType_ID != commonWMType) { resultStr = string.Format("Different WZ_Typ: {0} ({1} expected)", ihead.WMType_ID, commonWMType); return CommErr.WrongIPerlType; } resultStr = string.Format("Q2 pre-corrections: LR={0} RL={1}", ProcessData.CalculatedQ2PreCorrectionLR, ProcessData.CalculatedQ2PreCorrectionRL); return CommErr.None; } static CommErr SetIperlCommMilestoneReached(TestMethod testMethod, ConditionID id, ref string resultStr) { if (id < ConditionID.A || id >= ConditionID.Count) { resultStr = Strings.Error; return CommErr.WrongArguments; } testMethod.IperlCommMilestone[(int)id] = true; resultStr = string.Format(SequenceConditionOp.ConditionNameFmt, id); return CommErr.None; } #endif /// IPERL #endregion /// /// Called when communication with one watermeter is completed /// 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 CommCompletedHandler; void DoOnCommCompleted(object sender, CommCompletedEventArgs data) { try { /// /// Update the text message /// if (data.WMNr0 >= 0) messages[data.WMNr0].Text = data.CommMessage; /// /// Update head active/inactive switch /// if (data.WMNr0 >= 0 && data.CommErr == CommErr.HeadDisabledByUser) { /// iPerl head was disabled by the user ckbState[data.WMNr0] = false; checkBoxes[data.WMNr0].Checked = false; checkBoxes[data.WMNr0].Enabled = false; if (data.Ihead != null) data.Ihead.Disabled = true; if (data.Wm != null) data.Wm.Disabled = true; } else if (data.WMNr0 >= 0 && data.CommErr == CommErr.None) { /// One RFID communication successful => iPerl cannot be disabled by the user anymore ckbState[data.WMNr0] = true; checkBoxes[data.WMNr0].Checked = true; checkBoxes[data.WMNr0].Enabled = false; } /// /// Update opto-communication indication /// for (int i = 0; i < iperlHeads.Count; i++) { if (iperlHeads[i] == null || iperlHeads[i].Disabled) { counters[i].BackColor = DisabledColor; } else { switch (iperlHeads[i].CheckFlowDirection()) { case OptoHeadState.OptoAndDirOK: counters[i].BackColor = OptoAndDirOKColor; break; case OptoHeadState.DirNok: counters[i].BackColor = DirNokColor; break; default: case OptoHeadState.OptoNok: counters[i].BackColor = OptoNokColor; break; } } } #if !TURA_SPECIAL /// /// Branch /// lock (this) { if (++completedCommCount < 4) return; completedCommCount = 0; } #endif if (currentGroup < lastGroup) { /// Go to the next step / next group currentGroup++; } else if (currentActivityStep + 1 < multiTestParams.Count) { currentGroup = 0; currentActivityStep++; activityLabel.Text = multiTestParams[currentActivityStep].Activity; currentGroup++; } else { /// Wait until all threads are finished workerThreads[data.ThreadId].Join(2000); NormalClose(); } } catch (Exception e) { log.ErrorFormat("DoOnCommCompleted({0}) failed: {1}", data, e.Message); log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace); } } /// /// Called when communication with all watermeters is completed /// 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 AllCompletedHandler; void DoOnAllCompleted(object sender, AllCompletedEventArgs data) { Text = data.CommMessage; } /// /// Update test result representing RFID communication success/failure /// /// void UpdateRfidCommResult(IList tests) { DateTime endTime = DateTime.Now; int testTime = StateMachine.Time - startTimeSec; if (!tests.Contains(StateMachine.TestInstances[0].Test)) { tests.Insert(0, StateMachine.TestInstances[0].Test); /// Add RFID test as the 1st item } foreach (var test in tests) { Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part); if (tstRslt != null) { Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters); /// Auxiliary results ... not required /// Main results tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName; tstRslt.TestDone = true; tstRslt.StartTime = tstRslt.Batch.StartTime; tstRslt.EndTime = endTime; tstRslt.FlowSetTime = 0; tstRslt.MassOfEvapWater = 0; tstRslt.TestTime += testTime; /// [s] total communication time of all tests for (int i = 0; i < iperlHeads.Count; i++) { Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, waterMeterPositions0[i], CompoundMeterId.Single); if (meterRslt != null && iperlHeads[i] != null) { #if ORACLE_DB meterRslt.WaterMeter.WaterMeterData.WMTypeId = iperlHeads[i].WMType_ID; #endif meterRslt.WaterMeter.SerialNr = iperlHeads[i].SerialNr; meterRslt.Passed = (!iperlHeads[i].CommFailed && !iperlHeads[i].Disabled); meterRslt.TestDone = true; } } } } UiBridge.Bridge.OnTestCompleted(this, new UiBridge.TestCompletedEventArgs(string.Empty, null)); } #region Check boxes edit mode support private void checkBoxImage1_Click(object sender, EventArgs e) { ckbState[ckbIndex[0]] = checkBoxImage1.Checked; } private void checkBoxImage2_Click(object sender, EventArgs e) { ckbState[ckbIndex[1]] = checkBoxImage2.Checked; } private void checkBoxImage3_Click(object sender, EventArgs e) { ckbState[ckbIndex[2]] = checkBoxImage3.Checked; } private void checkBoxImage4_Click(object sender, EventArgs e) { ckbState[ckbIndex[3]] = checkBoxImage4.Checked; } private void checkBoxImage5_Click(object sender, EventArgs e) { ckbState[ckbIndex[4]] = checkBoxImage5.Checked; } private void checkBoxImage6_Click(object sender, EventArgs e) { ckbState[ckbIndex[5]] = checkBoxImage6.Checked; } private void checkBoxImage7_Click(object sender, EventArgs e) { ckbState[ckbIndex[6]] = checkBoxImage7.Checked; } private void checkBoxImage8_Click(object sender, EventArgs e) { ckbState[ckbIndex[7]] = checkBoxImage8.Checked; } private void checkBoxImage9_Click(object sender, EventArgs e) { ckbState[ckbIndex[8]] = checkBoxImage9.Checked; } private void checkBoxImage10_Click(object sender, EventArgs e) { ckbState[ckbIndex[9]] = checkBoxImage10.Checked; } private void checkBoxImage11_Click(object sender, EventArgs e) { ckbState[ckbIndex[10]] = checkBoxImage11.Checked; } private void checkBoxImage12_Click(object sender, EventArgs e) { ckbState[ckbIndex[11]] = checkBoxImage12.Checked; } private void checkBoxImage13_Click(object sender, EventArgs e) { ckbState[ckbIndex[12]] = checkBoxImage13.Checked; } private void checkBoxImage14_Click(object sender, EventArgs e) { ckbState[ckbIndex[13]] = checkBoxImage14.Checked; } private void checkBoxImage15_Click(object sender, EventArgs e) { ckbState[ckbIndex[14]] = checkBoxImage15.Checked; } private void checkBoxImage16_Click(object sender, EventArgs e) { ckbState[ckbIndex[15]] = checkBoxImage16.Checked; } private void checkBoxImage17_Click(object sender, EventArgs e) { ckbState[ckbIndex[16]] = checkBoxImage17.Checked; } private void checkBoxImage18_Click(object sender, EventArgs e) { ckbState[ckbIndex[17]] = checkBoxImage18.Checked; } private void checkBoxImage19_Click(object sender, EventArgs e) { ckbState[ckbIndex[18]] = checkBoxImage19.Checked; } private void checkBoxImage20_Click(object sender, EventArgs e) { ckbState[ckbIndex[19]] = checkBoxImage20.Checked; } private void checkBoxImage21_Click(object sender, EventArgs e) { ckbState[ckbIndex[20]] = checkBoxImage21.Checked; } private void checkBoxImage22_Click(object sender, EventArgs e) { ckbState[ckbIndex[21]] = checkBoxImage22.Checked; } private void checkBoxImage23_Click(object sender, EventArgs e) { ckbState[ckbIndex[22]] = checkBoxImage23.Checked; } private void checkBoxImage24_Click(object sender, EventArgs e) { ckbState[ckbIndex[23]] = checkBoxImage24.Checked; } private void checkBoxImage25_Click(object sender, EventArgs e) { ckbState[ckbIndex[24]] = checkBoxImage25.Checked; } private void checkBoxImage26_Click(object sender, EventArgs e) { ckbState[ckbIndex[25]] = checkBoxImage26.Checked; } private void checkBoxImage27_Click(object sender, EventArgs e) { ckbState[ckbIndex[26]] = checkBoxImage27.Checked; } private void checkBoxImage28_Click(object sender, EventArgs e) { ckbState[ckbIndex[27]] = checkBoxImage28.Checked; } private void checkBoxImage29_Click(object sender, EventArgs e) { ckbState[ckbIndex[28]] = checkBoxImage29.Checked; } private void checkBoxImage30_Click(object sender, EventArgs e) { ckbState[ckbIndex[29]] = checkBoxImage30.Checked; } private void checkBoxImage31_Click(object sender, EventArgs e) { ckbState[ckbIndex[30]] = checkBoxImage31.Checked; } private void checkBoxImage32_Click(object sender, EventArgs e) { ckbState[ckbIndex[31]] = checkBoxImage32.Checked; } private void checkBoxImage33_Click(object sender, EventArgs e) { ckbState[ckbIndex[32]] = checkBoxImage33.Checked; } private void checkBoxImage34_Click(object sender, EventArgs e) { ckbState[ckbIndex[33]] = checkBoxImage34.Checked; } private void checkBoxImage35_Click(object sender, EventArgs e) { ckbState[ckbIndex[34]] = checkBoxImage35.Checked; } private void checkBoxImage36_Click(object sender, EventArgs e) { ckbState[ckbIndex[35]] = checkBoxImage36.Checked; } private void checkBoxImage37_Click(object sender, EventArgs e) { ckbState[ckbIndex[36]] = checkBoxImage37.Checked; } private void checkBoxImage38_Click(object sender, EventArgs e) { ckbState[ckbIndex[37]] = checkBoxImage38.Checked; } private void checkBoxImage39_Click(object sender, EventArgs e) { ckbState[ckbIndex[38]] = checkBoxImage39.Checked; } private void checkBoxImage40_Click(object sender, EventArgs e) { ckbState[ckbIndex[39]] = checkBoxImage40.Checked; } private void checkBoxImage41_Click(object sender, EventArgs e) { ckbState[ckbIndex[40]] = checkBoxImage41.Checked; } private void checkBoxImage42_Click(object sender, EventArgs e) { ckbState[ckbIndex[41]] = checkBoxImage42.Checked; } private void checkBoxImage43_Click(object sender, EventArgs e) { ckbState[ckbIndex[42]] = checkBoxImage43.Checked; } private void checkBoxImage44_Click(object sender, EventArgs e) { ckbState[ckbIndex[43]] = checkBoxImage44.Checked; } private void checkBoxImage45_Click(object sender, EventArgs e) { ckbState[ckbIndex[44]] = checkBoxImage45.Checked; } private void checkBoxImage46_Click(object sender, EventArgs e) { ckbState[ckbIndex[45]] = checkBoxImage46.Checked; } private void checkBoxImage47_Click(object sender, EventArgs e) { ckbState[ckbIndex[46]] = checkBoxImage47.Checked; } private void checkBoxImage48_Click(object sender, EventArgs e) { ckbState[ckbIndex[47]] = checkBoxImage48.Checked; } /// /// Get states of checkboxes as one bitfield (long) /// /// Long bitfield private long GetCheckBoxStates() { long result = 0; for (int i = 0; i < 48; i++) { int wmNr0 = ckbIndex[i]; if (wmNr0 >= 0 && ckbState[wmNr0]) { result += (1L << wmNr0); } } return result; } /// /// Set checkboxes to states stored in a bitfield (long) /// private void SetCheckBoxStates(long state) { CheckBoxImage[] chkBoxes = new CheckBoxImage[48] { checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5, checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10, checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15, checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20, checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25, checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30, checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35, checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40, checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45, checkBoxImage46, checkBoxImage47, checkBoxImage48, }; for (int i = 0; i < 48; i++) { int wmNr0 = ckbIndex[i]; if (wmNr0 >= 0) { chkBoxes[i].Checked = ckbState[wmNr0] = ((state & (1L << wmNr0)) != 0); } } } private void saveButton_Click(object sender, EventArgs e) { Program.LocalSettings.OptoHeadsEnabled = GetCheckBoxStates(); Program.LocalSettings.Save(); DialogResult = DialogResult.OK; Close(); } #endregion private void iPerlCommunicationForm_FormClosing(object sender, FormClosingEventArgs e) { if (!forcedClose && !formCompleted && !checkBoxesEditMode) { e.Cancel = true; } } } }