diff --git a/NfcC7_DLL.Tests/NfcC7_DLL.Tests.csproj b/NfcC7_DLL.Tests/NfcC7_DLL.Tests.csproj index bb7d8ab83..7fa2e41a6 100644 --- a/NfcC7_DLL.Tests/NfcC7_DLL.Tests.csproj +++ b/NfcC7_DLL.Tests/NfcC7_DLL.Tests.csproj @@ -6,6 +6,10 @@ false + + 0 + + diff --git a/TBF.sln b/TBF.sln index ecb20ab6b..d795b9880 100644 --- a/TBF.sln +++ b/TBF.sln @@ -106,13 +106,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabelPrinting", "LabelPrint EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBFTests", "TBFTests\TBFTests.csproj", "{77EB589F-C670-4489-AAD6-2A3C02061FD1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic", "AppDiagnostic\AppDiagnostic.csproj", "{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}" - ProjectSection(ProjectDependencies) = postProject - {8F942729-F454-4C99-BA6C-746962065AE3} = {8F942729-F454-4C99-BA6C-746962065AE3} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedComponents", "SharedComponents\SharedComponents.csproj", "{8F942729-F454-4C99-BA6C-746962065AE3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sensus.iPerl.RfidCom", "..\iPerlHead\Sensus.iPerl.RfidCom\Sensus.iPerl.RfidCom.csproj", "{A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sensus.iPerl.TestConsole", "..\iPerlHead\Sensus.iPerl.TestConsole\Sensus.iPerl.TestConsole.csproj", "{5025ED8B-A94F-4E58-8BE0-68481B061609}" @@ -121,8 +114,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcS5_DLL", "..\NfcS5_DLL\N EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcC7_DLL", "NfcC7_DLL\NfcC7_DLL.csproj", "{53E75979-B530-4805-8FC9-B314F14A62BE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcC7_DLL.Tests", "NfcC7_DLL.Tests\NfcC7_DLL.Tests.csproj", "{715605C5-568B-48D6-9C09-2DC5F2E81F66}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -483,30 +474,6 @@ Global {77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|Mixed Platforms.Build.0 = Release|Any CPU {77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|x86.ActiveCfg = Release|Any CPU {77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|x86.Build.0 = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.ActiveCfg = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.Build.0 = Debug|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.Build.0 = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.ActiveCfg = Release|Any CPU - {FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.Build.0 = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|x86.ActiveCfg = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Debug|x86.Build.0 = Debug|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|Any CPU.Build.0 = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|x86.ActiveCfg = Release|Any CPU - {8F942729-F454-4C99-BA6C-746962065AE3}.Release|x86.Build.0 = Release|Any CPU {A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -555,18 +522,6 @@ Global {53E75979-B530-4805-8FC9-B314F14A62BE}.Release|Mixed Platforms.Build.0 = Release|Any CPU {53E75979-B530-4805-8FC9-B314F14A62BE}.Release|x86.ActiveCfg = Release|Any CPU {53E75979-B530-4805-8FC9-B314F14A62BE}.Release|x86.Build.0 = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|x86.ActiveCfg = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|x86.Build.0 = Debug|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Any CPU.Build.0 = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|x86.ActiveCfg = Release|Any CPU - {715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 7c378ef4a..2a662abad 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("3.9.2200.1")] -[assembly: AssemblyFileVersion("3.9.2200.1")] +[assembly: AssemblyVersion("3.9.2201.1")] +[assembly: AssemblyFileVersion("3.9.2201.1")] diff --git a/TBF/Rig/ControlBoard/Uni/UniCB.cs b/TBF/Rig/ControlBoard/Uni/UniCB.cs index ef5dd1d33..75f8d43aa 100644 --- a/TBF/Rig/ControlBoard/Uni/UniCB.cs +++ b/TBF/Rig/ControlBoard/Uni/UniCB.cs @@ -17,8 +17,7 @@ using TBF.Boxes; using TBF.Rig.GenericDevices; using TBF.Rig.Sequences; using TBF.UiBridge; -using AppDiagnostic; -using SharedComponents; + namespace TBF.Rig.ControlBoard.Uni { diff --git a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/GetDescription.cs b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/GetDescription.cs new file mode 100644 index 000000000..cf077205c --- /dev/null +++ b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/GetDescription.cs @@ -0,0 +1,27 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop +{ + public static class GetDescription + { + public static string ToDescription(this Enum en) + { + Type type = en.GetType(); + MemberInfo[] memInfo = type.GetMember(en.ToString()); + + if (memInfo != null && memInfo.Length > 0) + { + object[] attrs = memInfo[0].GetCustomAttributes( + typeof(DescriptionAttribute), + false); + + if (attrs != null && attrs.Length > 0) + return ((DescriptionAttribute)attrs[0]).Description; + } + + return en.ToString(); + } + } +} \ No newline at end of file diff --git a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/JsonDataFromPoseidon.cs b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/JsonDataFromPoseidon.cs index 71da1c0c1..e9dac08b3 100644 --- a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/JsonDataFromPoseidon.cs +++ b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/JsonDataFromPoseidon.cs @@ -1,22 +1,53 @@ - namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop { public class JsonDataFromPoseidon { - public bool? NfcTagDetected { get; set; } - public int? ProductType { get; set; } - public string ProductTypeVersion { get; set; } + public bool NfcTagDetected { get; set; } + public bool ReadingComplete { get; set; } + public string DeviceId { get; set; } + public string ProductType { get; set; } + public string ProductTypeVersion { get; set; } + public string CliVersion { get; set; } + public string Reading { get; set; } - public string Reading_Totalizer { get; set; } - public string Reading_Digits { get; set; } - public string Reading_Shift { get; set; } - public string Reading_Resolution { get; set; } + + public object Reading_Totalizer { get; set; } + public object Reading_FlowRate { get; set; } + public object Reading_FlowDirection { get; set; } + public object Reading_Digits { get; set; } + public object Reading_Shift { get; set; } + public object Reading_Resolution { get; set; } public string Reading_Units { get; set; } - public string Reading_FlowDirection { get; set; } - public string Reading_FlowRate { get; set; } + + public string MeterState { get; set; } public string CalibrationFactor { get; set; } - public bool? ReadingComplete { get; set; } + public string OpticalDataMode { get; set; } + + public string BuildInformation { get; set; } + public string ManufactureDate { get; set; } + public string MeterSize { get; set; } + public string FactoryId { get; set; } + public string CustomerText { get; set; } + + public string TestTotalizer { get; set; } + public string FlowUnits { get; set; } + public string ReadingUnits { get; set; } + + public string SpreadSpectrumParameters { get; set; } + + public string SpreadSpect_DisableSpreadSpectrum { get; set; } + public string SpreadSpect_AlwaysUseFullRateBags { get; set; } + public string SpreadSpect_PowerUp { get; set; } + public string SpreadSpect_HighNoise { get; set; } + public string SpreadSpect_EmptyPipe { get; set; } + public string SpreadSpect_BadAdc { get; set; } + public string SpreadSpect_InitLearningCompleteCount { get; set; } + public string SpreadSpect_MinOffsetLearningSampleCount { get; set; } + public string SpreadSpect_AdcShiftUpdateInterval { get; set; } + public string SpreadSpect_MaxPreviousAdcAge { get; set; } + public string SpreadSpect_AdcOffsetLearningGuard { get; set; } + public string SpreadSpect_DisplacementCorrectionCount { get; set; } } } \ No newline at end of file diff --git a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonCfg.cs b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonCfg.cs index bbd66db12..ada1b69fb 100644 --- a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonCfg.cs +++ b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonCfg.cs @@ -3,10 +3,12 @@ /// using System; using System.Collections.Generic; -using System.IO.Ports; +using System.ComponentModel; using System.Xml.Serialization; -using Common; using TBF.Rig.Generic; +using System.Linq; +using System.Reflection; +using Common; namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop { @@ -22,7 +24,22 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop /// public int ComPortNr; public string CliFileName; - public int MeterType; + + [XmlIgnore] + public SerialPortData.MeterProduct MeterType = SerialPortData.MeterProduct.Poseidon; + + [XmlElement("MeterProduct")] + public string MeterProductXml + { + get { return SerialPortData.MeterToString(MeterType); } + set { MeterType = SerialPortData.StringToMeter(value); } + } + + public SerialPortData.HatType HatType = SerialPortData.HatType.Mth; + public int TimeOut = 30; + public string MainMacro = SerialPortData.MacroTypes.readall.ToDescription(); + + /// Procedure parameters @@ -31,14 +48,68 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; } public override IParamsProvider CreateProcParamsProvider() { return new PoseidonProcParams(true); } + public static bool TryParseMeter( + string description, + out SerialPortData.MeterProduct meter) + { + var found = Enum.GetValues(typeof(SerialPortData.MeterProduct)) + .Cast() + .FirstOrDefault(e => + string.Equals( + e.GetType() + .GetField(e.ToString()) + .GetCustomAttribute() + ?.Description, + description, + StringComparison.OrdinalIgnoreCase)); + + if (!Equals(found, default(SerialPortData.MeterProduct)) || + string.Equals(description, "Poseidon", StringComparison.OrdinalIgnoreCase)) + { + meter = found; + return true; + } + + meter = default; + return false; + } + public static bool TryParseMacro( + string description, + out string macro) + { + var found = Enum.GetValues(typeof(SerialPortData.MacroTypes)) + .Cast() + .FirstOrDefault(e => + string.Equals( + e.GetType() + .GetField(e.ToString()) + .GetCustomAttribute() + ?.Description, + description, + StringComparison.OrdinalIgnoreCase)); + + if (!Equals(found, default(SerialPortData.MacroTypes)) || + string.Equals(description, "readall", StringComparison.OrdinalIgnoreCase)) + { + macro = found.ToDescription(); + return true; + } + + macro = default; + return false; + } string[] paramNames = new string[] { "Serial port number", /// 0 "CLI program name", /// 1 "Meter Type", /// 2 + "Hat Type", /// 3 + "TimeOut [s]", /// 4 + "Main Macro" /// 5 }; + public string ParamName(int i) { return paramNames[i]; } public int ParamsCount() { return paramNames.Length; } @@ -51,8 +122,27 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop case 1: return new string[] { "HatCLI.exe"}; case 2: - return new string[] { "74" }; - + return new string[] { + SerialPortData.MeterProduct.Poseidon.ToDescription() , + SerialPortData.MeterProduct.Ally.ToDescription(), + SerialPortData.MeterProduct.IperlPlus.ToDescription(), + SerialPortData.MeterProduct.IperlLegacy.ToDescription() + }; + case 3: + return new string[] + { + SerialPortData.HatType.Mth.ToDescription(), + SerialPortData.HatType.Harry.ToDescription() + }; + case 4: + return new string[] { "30", "60", "90"}; + case 5: + string macro0 = SerialPortData.MacroTypes.readall.ToDescription(); + string macro1 = SerialPortData.MacroTypes.macro1.ToDescription(); + string macro2 = SerialPortData.MacroTypes.macro2.ToDescription(); + string macro3 = SerialPortData.MacroTypes.macro3.ToDescription(); + + return new string[] { macro0, macro1, macro2, macro3 }; default: return null; } @@ -60,12 +150,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop public IComponentCfgCtrl GetControl(IList cmpntEntities) { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); } - + public void InitializeAll() { ComPortNr = 3; - CliFileName = "HatCLI.exe"; - MeterType = 74; + CliFileName = "HatCLI.exe"; + MeterType = SerialPortData.MeterProduct.Poseidon; + HatType = SerialPortData.HatType.Mth; + TimeOut = 30; + MainMacro = SerialPortData.MacroTypes.readall.ToDescription(); } public bool ValidateParam(int i, string strValue, out string message) @@ -83,8 +176,17 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop if(System.Text.RegularExpressions.Regex.IsMatch(strValue, @"^[a-zA-Z0-9_-]+\.exe$")) return true; //validate exe file name break; case 2: + if (TryParseMeter(strValue, out var meter)) return true; + break; + case 3: + if (TryParseHatType(strValue, out var hatType)) return true; + break; + case 4: if (int.TryParse(strValue, out idummy) && idummy > 0) return true; break; + case 5: + if (TryParseMacro(strValue, out string macroType)) return true; + break; default: message = "Invalid index"; return false; @@ -100,11 +202,38 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop { case 0: ComPortNr = int.Parse(str); return CfgUpdateFlags.RestartRqrd; case 1: CliFileName = str; return CfgUpdateFlags.RestartRqrd; - case 2: MeterType = int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 2: TryParseMeter(str, out MeterType); return CfgUpdateFlags.RestartRqrd; + case 3: TryParseHatType(str, out HatType); return CfgUpdateFlags.RestartRqrd; + case 4: TimeOut = int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 5: MainMacro = str; return CfgUpdateFlags.RestartRqrd; default: return CfgUpdateFlags.None; } } + public static bool TryParseHatType(string description, out SerialPortData.HatType hatType) + { + var found = Enum.GetValues(typeof(SerialPortData.HatType)) + .Cast() + .FirstOrDefault(e => + string.Equals( + e.GetType() + .GetField(e.ToString()) + .GetCustomAttribute() + ?.Description, + description, + StringComparison.OrdinalIgnoreCase)); + + if (!Equals(found, default(SerialPortData.HatType)) || + string.Equals(description, "Mth", StringComparison.OrdinalIgnoreCase)) + { + hatType = found; + return true; + } + + hatType = default; + return false; + } + public bool UpdateEmbeddedDbEntity() { return true; /// =OK, do nothing @@ -139,9 +268,12 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop case 0: return ComPortNr.ToString(); case 1: return CliFileName; case 2: return MeterType.ToString(); + case 3: return HatType.ToString(); + case 4: return TimeOut.ToString(); + case 5: return MainMacro; default: - return string.Format("{0}: Com{1}, CliName =`{2}`, MeterType = {3}", - Name, ComPortNr, CliFileName, MeterType); + return string.Format("{0}: Com{1}, CliName =`{2}`, MeterType = {3}, HatType = {4}, TimeOut = {5}", + Name, ComPortNr, CliFileName, MeterType, HatType, TimeOut); } } @@ -150,6 +282,9 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop prms.ComPortNr = this.ComPortNr; prms.CliFileName = this.CliFileName; prms.MeterType = this.MeterType; + prms.HatType = this.HatType; + prms.TimeOut = this.TimeOut; + prms.MainMacro = this.MainMacro; prms.ProcParams = this.ProcParams; } } diff --git a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonReader.cs b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonReader.cs index 9cd4702d7..4e3d30588 100644 --- a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonReader.cs +++ b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/PoseidonReader.cs @@ -282,7 +282,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop /// Prepare serial port serialPort = new SerialPortData(string.Format("COM{0}", registerReaderCfg.ComPortNr), registerReaderCfg.CliFileName, - registerReaderCfg.MeterType); + registerReaderCfg.MeterType, //registerReaderCfg.MeterType, //MeterProduct.Poseidon + registerReaderCfg.HatType,//HatType.Mth + registerReaderCfg.TimeOut, //timeoutSeconds + registerReaderCfg.MainMacro + ); //TODO BUMI prepare serial port - for us do nothing diff --git a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/SerialPortData.cs b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/SerialPortData.cs index 123273e24..2f7bf6f76 100644 --- a/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/SerialPortData.cs +++ b/TBF/Rig/RegisterReaders/PoseidonCmdStartStop/SerialPortData.cs @@ -1,5 +1,8 @@ using System; using System.IO; +using System.ComponentModel; +using System.Reflection; +using System.Xml.Serialization; namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop { @@ -22,30 +25,228 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop } public string CmdClientName { get; set; } = "HalCli.exe"; public string PortName { get; set; } - public int MeterType { get; set; } + // Backward compatibility: old numeric meter type + public int? OldMeterType { get; set; } - public enum EMeterArg { + // New v2.0 parameters + public HatType Hat { get; set; } = HatType.Mth; + public int TimeoutSeconds { get; set; } = 10; + public string Macro { get; set; } = "readall"; + + [XmlIgnore] + public MeterProduct Meter { get; set; } = MeterProduct.Poseidon; + + [XmlElement("MeterProduct")] + public string MeterXml + { + get { return MeterToString(Meter); } + set { Meter = StringToMeter(value); } + } + + public static string MeterToString(MeterProduct meter) + { + switch (meter) + { + case MeterProduct.Poseidon: + return "Poseidon"; + case MeterProduct.Ally: + return "ally"; + case MeterProduct.IperlPlus: + return "iperlplus"; + case MeterProduct.IperlLegacy: + return "iperllegacy"; + default: + return "Poseidon"; + } + } + + public static MeterProduct StringToMeter(string value) + { + if (string.IsNullOrWhiteSpace(value)) + return MeterProduct.Poseidon; + + // old numeric values: 74, 7889, etc. + if (int.TryParse(value, out _)) + return MeterProduct.Poseidon; + + if (string.Equals(value, "cTouchRead", StringComparison.OrdinalIgnoreCase)) + return MeterProduct.Poseidon; + + if (string.Equals(value, "Poseidon", StringComparison.OrdinalIgnoreCase)) + return MeterProduct.Poseidon; + + if (string.Equals(value, "ally", StringComparison.OrdinalIgnoreCase)) + return MeterProduct.Ally; + + if (string.Equals(value, "iperlplus", StringComparison.OrdinalIgnoreCase)) + return MeterProduct.IperlPlus; + + if (string.Equals(value, "iperllegacy", StringComparison.OrdinalIgnoreCase)) + return MeterProduct.IperlLegacy; + + return MeterProduct.Poseidon; + } + + public static bool TryParseMeter( + string description, + out SerialPortData.MeterProduct meter) + { + foreach (SerialPortData.MeterProduct value in + Enum.GetValues(typeof(SerialPortData.MeterProduct))) + { + var attr = value.GetType() + .GetField(value.ToString()) + .GetCustomAttribute(); + + if (string.Equals(attr?.Description, description, StringComparison.OrdinalIgnoreCase) || + string.Equals(value.ToString(), description, StringComparison.OrdinalIgnoreCase)) + { + meter = value; + return true; + } + } + + meter = SerialPortData.MeterProduct.Poseidon; + return false; + } + + public enum MacroTypes + { + [Description("readall")] + readall = 0, + [Description("readmacro1")] + macro1 = 1, + [Description("readmacro2")] + macro2 = 2, + [Description("readmacro3")] + macro3 = 3 + } + + public enum HatType + { + [Description("Mth")] + Mth = 0, + [Description("Harry")] + Harry = 1 + } + + public enum MeterProduct + { + [Description("Poseidon")] + [XmlEnum("74")] + Poseidon = 74, + + [Description("ally")] + [XmlEnum("ally")] + Ally = 75, + + [Description("iperlplus")] + [XmlEnum("iperlplus")] + IperlPlus = 76, + + [Description("iperllegacy")] + [XmlEnum("iperllegacy")] + IperlLegacy = 77 + } + + public enum EMeterArg + { Calibration = 0, AllParams = 2, DeviceId = 3, - } - EMeterArg _eMeterArg = EMeterArg.AllParams; + + // New macro operations - just waste + ReadMacro1 = 10, + ReadMacro2 = 11, + ReadMacro3 = 12 + } - public string DefaultArgSettings(EMeterArg eMeterArg) + public string DefaultArgSettings(EMeterArg eMeterArg) { + string commonArgs = BuildCommonArgs(); + switch (eMeterArg) { case EMeterArg.Calibration: - return $"-p {PortName} -m {MeterType} --operation write --parameter Calibration --value 1"; - case EMeterArg.AllParams: - return $"-p {PortName} -m {MeterType} --operation readall"; + return $"{commonArgs} --operation write --parameter Calibration --value 1"; + case EMeterArg.DeviceId: - return $"-p {PortName} -m {MeterType} --operation read --parameter DeviceId"; + return $"{commonArgs} --operation read --parameter DeviceId"; + + case EMeterArg.AllParams: + case EMeterArg.ReadMacro1: + case EMeterArg.ReadMacro2: + case EMeterArg.ReadMacro3: + return $"{commonArgs} --operation {Macro}"; default: return ""; } } + private string BuildCommonArgs() + { + return $"-p {PortName} " + + $"-m {GetMeterArgument()} " + + $"--hat {GetHatArgument()} " + + $"--timeout {TimeoutSeconds}"; + } + + private string GetMeterArgument() + { + // Old compatibility mode + if (OldMeterType.HasValue) + return OldMeterType.Value.ToString(); + + switch (Meter) + { + case MeterProduct.Poseidon: + return "Poseidon"; + + case MeterProduct.Ally: + return "ally"; + + case MeterProduct.IperlPlus: + return "iperlplus"; + + case MeterProduct.IperlLegacy: + return "iperllegacy"; + + default: + return "Poseidon"; + } + } + + private string GetHatArgument() + { + switch (Hat) + { + case HatType.Harry: + return "harry"; + + case HatType.Mth: + default: + return "mth"; + } + } + + // New constructor for v2.0 + public SerialPortData( + string portName, + string cmdClientName, + MeterProduct meter = MeterProduct.Poseidon, + HatType hat = HatType.Mth, + int timeoutSeconds = 10, + string macro = "readall") + { + PortName = portName; + CmdClientName = cmdClientName; + Meter = meter; + Hat = hat; + TimeoutSeconds = timeoutSeconds; + Macro = macro; + } + + // Old constructor kept for backward compatibility public SerialPortData( string portName, string cmdClientName, @@ -53,7 +254,9 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop { PortName = portName; CmdClientName = cmdClientName; - MeterType = meterType; + OldMeterType = meterType; } } + + } \ No newline at end of file diff --git a/TBF/Rig/Sequences/MainSeq.cs b/TBF/Rig/Sequences/MainSeq.cs index b71692d16..052ba9ed2 100644 --- a/TBF/Rig/Sequences/MainSeq.cs +++ b/TBF/Rig/Sequences/MainSeq.cs @@ -18,7 +18,6 @@ using TBF.Rig.Network.RestAPI; using TBF.Rig.Network.RestAPI.facade; using TBF.Rig.Output.Printers.GroupPrinting.Single; using TBF.UiBridge; -using SharedComponents; using System.Text; using TBF.Rig.RegisterReaders.CommonRR.IPerl; using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication; @@ -1548,7 +1547,7 @@ namespace TBF.Rig.Sequences } // ✍️ Uloženie do vlastného logu - LiveLogCache.Instance.AddLog(logBuilder.ToString()); + //LiveLogCache.Instance.AddLog(logBuilder.ToString()); Bridge.OnError(this, "Chyba pri aktualizácii výsledkov v MySQL."); goto error; diff --git a/TBF/Rig/Uni/FlowMeter/FlowMeter.cs b/TBF/Rig/Uni/FlowMeter/FlowMeter.cs index 3700344e4..847ea93cd 100644 --- a/TBF/Rig/Uni/FlowMeter/FlowMeter.cs +++ b/TBF/Rig/Uni/FlowMeter/FlowMeter.cs @@ -10,7 +10,7 @@ using SchematicDrawing; using TBF.Rig.ControlBoard.Uni; using TBF.Boxes; using TBF.Resources; -using AppDiagnostic; + namespace TBF.Rig.Uni.FlowMeter { diff --git a/TBF/Rig/Uni/RegValveLowRegulTimeSaturation/RegValve.cs b/TBF/Rig/Uni/RegValveLowRegulTimeSaturation/RegValve.cs index d43935b5e..45874533a 100644 --- a/TBF/Rig/Uni/RegValveLowRegulTimeSaturation/RegValve.cs +++ b/TBF/Rig/Uni/RegValveLowRegulTimeSaturation/RegValve.cs @@ -7,7 +7,6 @@ using log4net; using SchematicDrawing; using TBF.Rig.ControlBoard.Uni; using TBF.Boxes; -using SharedComponents; namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation { diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index cbaf2f9b6..b8a4bffa5 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -63,6 +63,7 @@ bin\Debug\ TRACE;DEBUG;CAMERA;LANG_PL;IPERL; full + 4 AnyCPU prompt MinimumRecommendedRules.ruleset @@ -74,6 +75,7 @@ TRACE;CAMERA;LANG_PL;IPERL; true pdbonly + 4 AnyCPU prompt MinimumRecommendedRules.ruleset @@ -1324,6 +1326,7 @@ + @@ -3970,10 +3973,6 @@ {5954d496-caab-4f7a-bde2-bdc8f47dab19} NfcS5_DLL - - {fa9abad1-7184-4295-ade8-d44f2e3de6b2} - AppDiagnostic - {c8939821-ba5c-4988-a3d0-bf53b74865c7} Common @@ -4014,10 +4013,6 @@ {0f79ca69-9dbc-41f3-a6fc-5a2937365343} SchematicDrawing - - {8f942729-f454-4c99-ba6c-746962065ae3} - SharedComponents - {211b5e3f-9996-48a7-abde-c878dd2d71c2} SharedDatabase @@ -4035,4 +4030,4 @@ --> - \ No newline at end of file + diff --git a/TBF/UI/MainWnd.cs b/TBF/UI/MainWnd.cs index 8a046c81e..84471189e 100644 --- a/TBF/UI/MainWnd.cs +++ b/TBF/UI/MainWnd.cs @@ -13,13 +13,9 @@ using Common; using Config.Entities; using Dirichlet.Numerics; using SchematicDrawing; -using SharedDatabase; using TBF.Resources; using TBF.UiBridge; using TBF.UI.Shared; -using AppDiagnostic; -using SharedComponents; -using System.Diagnostics; using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication; namespace TBF.UI @@ -1164,8 +1160,8 @@ namespace TBF.UI ILog loger = LogManager.GetLogger("logCache"); log.Debug("ahoj, ideme");*/ - LiveLogCache.Instance.AddLog("=== Live diagnostic entry ==="); - DiagApi liveDiagApi = new DiagApi(); + //LiveLogCache.Instance.AddLog("=== Live diagnostic entry ==="); + //DiagApi liveDiagApi = new DiagApi(); /*try { diff --git a/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTest.cs b/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTest.cs index b65f1a0b7..a45debb67 100644 --- a/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTest.cs +++ b/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTest.cs @@ -17,6 +17,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop { string allOutput = " {\n \"DeviceId\": \"1000000267\"\n}\n"; CliRunner cliRunner = new CliRunner(false); + string json = cliRunner.ExtractJson(allOutput); Assert.IsFalse(string.IsNullOrEmpty(json)); @@ -25,8 +26,10 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop [TestMethod] public void ExtractJson_Test2() { - string allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n"; + string allOutput = + "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n"; CliRunner cliRunner = new CliRunner(false); + string json = cliRunner.ExtractJson(allOutput); Assert.IsFalse(string.IsNullOrEmpty(json)); @@ -35,7 +38,8 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop [TestMethod] public void TryJsonStringDeserialize_Test() { - string allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n"; + string allOutput = + "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n"; CliRunner cliRunner = new CliRunner(false); string json = cliRunner.ExtractJson(allOutput); @@ -48,13 +52,115 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.AreEqual("0003292.1", dto.Reading); Assert.AreEqual("000329218", dto.Reading_Totalizer); Assert.AreEqual(true, dto.NfcTagDetected); - Assert.AreEqual(74, dto.ProductType); + Assert.AreEqual("74", dto.ProductType); + } + + [TestMethod] + public void SerialPortData_NewDefaults_ShouldUsePoseidonMthTimeout10() + { + SerialPortData serialPort = new SerialPortData( + "COM3", + "HalCli.exe", + SerialPortData.MeterProduct.Poseidon); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); + + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 10 --operation readall", + args); + } + + [TestMethod] + public void SerialPortData_HarryHat_ShouldUseHarry() + { + SerialPortData serialPort = new SerialPortData( + "COM3", + "HalCli.exe", + SerialPortData.MeterProduct.Poseidon, + SerialPortData.HatType.Harry, + 30); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.DeviceId); + + Assert.AreEqual( + "-p COM3 -m Poseidon --hat harry --timeout 30 --operation read --parameter DeviceId", + args); + } + + [TestMethod] + public void SerialPortData_OldConstructor_ShouldKeepOldMeterType() + { + SerialPortData serialPort = new SerialPortData("COM3", "HalCli.exe", 74); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); + + Assert.AreEqual( + "-p COM3 -m 74 --hat mth --timeout 10 --operation readall", + args); + } + + [TestMethod] + public void SerialPortData_NewMeterTypes_ShouldGenerateCorrectMeterNames() + { + var testCases = new[] + { + new { Meter = SerialPortData.MeterProduct.Poseidon, Expected = "Poseidon" }, + new { Meter = SerialPortData.MeterProduct.Ally, Expected = "ally" }, + new { Meter = SerialPortData.MeterProduct.IperlPlus, Expected = "iperlplus" }, + new { Meter = SerialPortData.MeterProduct.IperlLegacy, Expected = "iperllegacy" } + }; + + foreach (var testCase in testCases) + { + SerialPortData serialPort = new SerialPortData( + "COM3", + "HalCli.exe", + testCase.Meter); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); + + StringAssert.Contains(args, $"-m {testCase.Expected}"); + } + } + + [TestMethod] + public void SerialPortData_ReadMacros_ShouldGenerateCorrectOperations() + { + SerialPortData serialPort = new SerialPortData( + "COM3", + "HalCli.exe", + SerialPortData.MeterProduct.Poseidon); + + serialPort.Macro = "readmacro1"; + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro1", + serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro1)); + + serialPort.Macro = "readmacro2"; + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro2", + serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro2)); + + serialPort.Macro = "readmacro3"; + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro3", + serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro3)); + + serialPort.Macro = "xxx"; + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 10 --operation xxx", + serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams)); } [TestMethod] public void RunMultipleTimesTestProgram_CheckParalelWork() { - SerialPortData serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74); + SerialPortData serialPort = new SerialPortData( + "COM3", + "cmdSleepTest.exe", + SerialPortData.MeterProduct.Poseidon, + SerialPortData.HatType.Mth, + 10); if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath)) { @@ -92,9 +198,11 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}"); TimeSpan delta = endTime - startTime; + Console.WriteLine( $"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " + $"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}"); + Console.WriteLine($"Total tasks: {cliRunner.TaskPool.Count}"); foreach (CliTaskInfo taskInfo in cliRunner.TaskPool) @@ -108,12 +216,15 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.IsNotNull(task, "Expected Task."); JsonDataFromPoseidon jsonDataFromPoseidon = task.Result; + Console.WriteLine($"Result: {jsonDataFromPoseidon?.DeviceId}"); + Assert.IsNotNull(jsonDataFromPoseidon); } else { - Assert.Fail($"Task did not complete successfully. State={taskInfo.State}, Status={taskInfo.Task.Status}"); + Assert.Fail( + $"Task did not complete successfully. State={taskInfo.State}, Status={taskInfo.Task.Status}"); } } @@ -123,7 +234,12 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop [TestMethod] public async Task RunMultipleTimesTestProgram_CheckParalelWorkCumulative() { - SerialPortData serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74); + SerialPortData serialPort = new SerialPortData( + "COM3", + "cmdSleepTest.exe", + SerialPortData.MeterProduct.Poseidon, + SerialPortData.HatType.Mth, + 10); if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath)) { @@ -179,9 +295,11 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}"); TimeSpan delta = endTime - startTime; + Console.WriteLine( $"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " + $"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}"); + Console.WriteLine($"Total tasks: {cliRunnerList.Sum(runner => runner.TaskPool.Count)}"); for (int iCliRunner = 0; iCliRunner < cliRunnerList.Count; iCliRunner++) @@ -199,7 +317,9 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.IsNotNull(task, "Expected Task."); JsonDataFromPoseidon jsonDataFromPoseidon = task.Result; + results += $" ID: {jsonDataFromPoseidon?.DeviceId}"; + Assert.IsNotNull(jsonDataFromPoseidon); } else @@ -214,5 +334,115 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.IsTrue((cliRunnerList.Count * oneEndTime.Ticks) > delta.Ticks); } + + + [TestMethod] + public void TryJsonStringDeserialize_ReadMacro1_Test() + { + string allOutput = @"{ + ""DeviceId"": ""1000000176"", + ""MeterState"": ""MB012501A177"", + ""CalibrationFactor"": ""3250"", + ""Reading_Units"": ""0"", + ""Reading_Totalizer"": 0, + ""Reading_FlowRate"": 0, + ""Reading_FlowDirection"": 0, + ""Reading_Digits"": 0, + ""Reading_Shift"": 0, + ""Reading_Resolution"": 0, + ""OpticalDataMode"": ""199"", + ""MeterSize"": ""3"", + ""ManufactureDate"": ""2026/04/20 00:56:00"", + ""ProductType"": ""74"", + ""ProductTypeVersion"": ""B1.0.29"", + ""CliVersion"": ""2.0.0.0"", + ""ReadingComplete"": true, + ""NfcTagDetected"": true + }"; + + CliRunner cliRunner = new CliRunner(false); + string json = cliRunner.ExtractJson(allOutput); + + bool ok = cliRunner.TryJsonStringDeserialize(json, out var dto); + + Assert.IsTrue(ok); + Assert.IsNotNull(dto); + Assert.AreEqual("1000000176", dto.DeviceId); + Assert.AreEqual("MB012501A177", dto.MeterState); + Assert.AreEqual("3250", dto.CalibrationFactor); + Assert.AreEqual("199", dto.OpticalDataMode); + Assert.AreEqual("3", dto.MeterSize); + Assert.AreEqual("74", dto.ProductType); + Assert.AreEqual("2.0.0.0", dto.CliVersion); + Assert.IsTrue(dto.ReadingComplete); + Assert.IsTrue(dto.NfcTagDetected); + } + + [TestMethod] + public void TryJsonStringDeserialize_ReadMacro2_Test() + { + string allOutput = @"{ + ""DeviceId"": ""1000000176"", + ""Reading_Units"": ""0"", + ""Reading_Totalizer"": 0, + ""Reading_FlowRate"": 0, + ""Reading_FlowDirection"": 0, + ""Reading_Digits"": 0, + ""Reading_Shift"": 0, + ""Reading_Resolution"": 0, + ""ProductType"": ""74"", + ""ProductTypeVersion"": ""B1.0.29"", + ""CliVersion"": ""2.0.0.0"", + ""ReadingComplete"": true, + ""NfcTagDetected"": true + }"; + + CliRunner cliRunner = new CliRunner(false); + string json = cliRunner.ExtractJson(allOutput); + + bool ok = cliRunner.TryJsonStringDeserialize(json, out var dto); + + Assert.IsTrue(ok); + Assert.IsNotNull(dto); + Assert.AreEqual("1000000176", dto.DeviceId); + Assert.AreEqual("0", dto.Reading_Units); + Assert.AreEqual("74", dto.ProductType); + Assert.AreEqual("B1.0.29", dto.ProductTypeVersion); + Assert.AreEqual("2.0.0.0", dto.CliVersion); + Assert.IsTrue(dto.ReadingComplete); + Assert.IsTrue(dto.NfcTagDetected); + } + + [TestMethod] + public void TryJsonStringDeserialize_ReadMacro3_Test() + { + string allOutput = @"{ + ""DeviceId"": ""1000000176"", + ""Reading_Units"": ""0"", + ""Reading_Totalizer"": 0, + ""Reading_FlowRate"": 0, + ""Reading_FlowDirection"": 0, + ""Reading_Digits"": 0, + ""Reading_Shift"": 0, + ""Reading_Resolution"": 0, + ""CliVersion"": ""2.0.0.0"", + ""ReadingComplete"": true, + ""NfcTagDetected"": true + }"; + + CliRunner cliRunner = new CliRunner(false); + string json = cliRunner.ExtractJson(allOutput); + + bool ok = cliRunner.TryJsonStringDeserialize(json, out var dto); + + Assert.IsTrue(ok); + Assert.IsNotNull(dto); + Assert.AreEqual("1000000176", dto.DeviceId); + Assert.AreEqual("0", dto.Reading_Units); + Assert.AreEqual("2.0.0.0", dto.CliVersion); + Assert.IsTrue(dto.ReadingComplete); + Assert.IsTrue(dto.NfcTagDetected); + } + } } \ No newline at end of file diff --git a/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTimeoutTest.cs b/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTimeoutTest.cs index 66a0a303a..c144e22d2 100644 --- a/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTimeoutTest.cs +++ b/TBFTests/Rig/RegisterReaders/PoseidonCmdStartStop/CliRunnerTimeoutTest.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -12,10 +11,20 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop [TestSubject(typeof(CliRunner))] public class CliRunnerTimeoutTest { + private static SerialPortData CreateDefaultSerialPortData() + { + return new SerialPortData( + "COM3", + "cmdSleepTest.exe", + SerialPortData.MeterProduct.Poseidon, + SerialPortData.HatType.Mth, + 30, + TBF.Rig.RegisterReaders.PoseidonCmdStartStop.GetDescription.ToDescription(SerialPortData.MacroTypes.readall)); + } + private static string GetCmdSleepTestPath() { - var serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74); - return serialPort.SerialPortCmdClientPath; + return CreateDefaultSerialPortData().SerialPortCmdClientPath; } private static void EnsureExeExists(string exePath) @@ -28,6 +37,33 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop } } + [TestMethod] + public void SerialPortData_ForTimeoutTests_ShouldUseVersion2Defaults() + { + SerialPortData serialPort = CreateDefaultSerialPortData(); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); + + Assert.AreEqual( + "-p COM3 -m Poseidon --hat mth --timeout 30 --operation readall", + args); + } + + [TestMethod] + public void SerialPortData_ForTimeoutTests_ShouldStillSupportOldMeterType() + { + SerialPortData serialPort = new SerialPortData( + "COM3", + "cmdSleepTest.exe", + 74); + + string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); + + Assert.AreEqual( + "-p COM3 -m 74 --hat mth --timeout 10 --operation readall", + args); + } + [TestMethod] public async Task Timeout_ShouldBeDetected_ForLongRunningTask() { @@ -85,7 +121,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop } catch { - // let assertions inspect states + // Let assertions inspect states. } cliRunner.RefreshTaskStates(); @@ -101,6 +137,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.IsTrue(taskInfo.UseResult, "Completed task should remain usable."); var task = taskInfo.Task as Task; + Assert.IsNotNull(task); Assert.AreEqual(TaskStatus.RanToCompletion, task.Status); Assert.IsNotNull(task.Result); @@ -123,7 +160,9 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop cliRunner.RefreshTaskStates(); Assert.AreEqual(2, cliRunner.TaskPool.Count); - Assert.AreEqual(1, cliRunner.TaskPool.Count(t => t.State == CliTaskState.Completed), + Assert.AreEqual( + 1, + cliRunner.TaskPool.Count(t => t.State == CliTaskState.Completed), "Exactly one fast task should be completed before timeout handling."); cliRunner.CancelUndoneTasksAsTimedOut(); @@ -136,6 +175,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.IsFalse(timedOutTask.UseResult); var completed = doneTask.Task as Task; + Assert.IsNotNull(completed); Assert.AreEqual(TaskStatus.RanToCompletion, completed.Status); Assert.IsNotNull(completed.Result); @@ -153,12 +193,15 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop await Task.Delay(150); - Assert.IsFalse(cliRunner.AreTasksDone(), "Task should still be running before timeout cancellation."); + Assert.IsFalse( + cliRunner.AreTasksDone(), + "Task should still be running before timeout cancellation."); cliRunner.CancelUndoneTasksAsTimedOut(); cliRunner.RefreshTaskStates(); - Assert.IsTrue(cliRunner.AreTasksDone(), + Assert.IsTrue( + cliRunner.AreTasksDone(), "After timed out tasks are marked, runner should report no running tasks."); } @@ -193,7 +236,9 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop for (int i = 0; i < 5; i++) { - cliRunner.AddRunAndCaptureJsonAsync(exePath, "sleep=5000"); + cliRunner.AddRunAndCaptureJsonAsync( + exePath, + "sleep=5000"); } await Task.Delay(200); @@ -214,7 +259,9 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop var cliRunner = new CliRunner(false); - cliRunner.AddRunAndCaptureJsonAsync(exePath, "sleep=50 invalidjson=true"); + cliRunner.AddRunAndCaptureJsonAsync( + exePath, + "sleep=50 invalidjson=true"); try { @@ -222,6 +269,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop } catch { + // Let assertions inspect states. } cliRunner.RefreshTaskStates(); @@ -229,19 +277,20 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop Assert.AreEqual(1, cliRunner.TaskPool.Count); var taskInfo = cliRunner.TaskPool.Single(); + Assert.AreEqual(CliTaskState.Completed, taskInfo.State); var task = taskInfo.Task as Task; + Assert.IsNotNull(task); Assert.AreEqual(TaskStatus.RanToCompletion, task.Status); - // depending on your TryJsonStringDeserialize fallback, - // result may be null or an empty/default object - // so avoid asserting UseResult=false here - // instead assert no valid device id + // Depending on TryJsonStringDeserialize fallback, + // result may be null or an empty/default object. if (task.Result != null) { - Assert.IsTrue(string.IsNullOrEmpty(task.Result.DeviceId), + Assert.IsTrue( + string.IsNullOrEmpty(task.Result.DeviceId), "Invalid JSON should not produce a valid DeviceId."); } }