Add AllyReader and AllyCalibration support with tests: Introduce new register readers, calibration methods, and comprehensive unit tests for integration and functionality validation. Update project files accordingly.
260 lines
11 KiB
C#
260 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using Common;
|
|
using Config.Entities;
|
|
using Results.Entities;
|
|
using TBF.Rig.RegisterReaders.AllyReader;
|
|
using TBF.Rig.RegisterReaders.AllyReader.Communication;
|
|
using TBF.Rig.Sequences;
|
|
using TBF.UiBridge;
|
|
|
|
namespace TBF.Rig.TestMethods.AllyCalibration
|
|
{
|
|
public class AllyCalibrationSeq : SequenceBase
|
|
{
|
|
private const byte InitialMeterMode = 0x09;
|
|
private const byte ActiveMeterMode = 0x02;
|
|
private const byte DiagnosticLedCalibrationMode = 0xC2;
|
|
private const string DisplayVolume = "01134010";
|
|
private const byte LcdTimeoutSeconds = 30;
|
|
private const ushort OffsetLearningSamples = 1000;
|
|
private const ushort OffsetLearningDelaySeconds = 1;
|
|
|
|
public IList<Event> Execute(
|
|
Test test,
|
|
int repetitionNr,
|
|
TestMethod method,
|
|
TestMethodCfg cfg,
|
|
TestMethodParams parameters)
|
|
{
|
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
|
|
|
TestRslt testResult = BatchRslts.GetTestRslt(test.Name, 0);
|
|
if (testResult != null)
|
|
testResult.StartTime = DateTime.Now;
|
|
|
|
List<string> messages = new List<string>();
|
|
|
|
for (int position = 0; position < BatchRslts.WMPositionsCount; position++)
|
|
{
|
|
Results.Entities.WaterMeter waterMeter = BatchRslts.Batch.WaterMeters[position];
|
|
if (waterMeter == null || waterMeter.Disabled)
|
|
continue;
|
|
|
|
MeterTestRslt meterResult = BatchRslts.GetMeterTestRslt(
|
|
test.Name,
|
|
position,
|
|
CompoundMeterId.Single);
|
|
|
|
AllyMeterReader reader = sensPath != null &&
|
|
sensPath.RegisterReaders != null &&
|
|
position < sensPath.RegisterReaders.Length
|
|
? sensPath.RegisterReaders[position] as AllyMeterReader
|
|
: null;
|
|
|
|
bool passed;
|
|
string resultMessage;
|
|
if (reader == null)
|
|
{
|
|
passed = false;
|
|
resultMessage = "ALLY" + (position + 1) + ": ALLY reader is not configured.";
|
|
}
|
|
else
|
|
{
|
|
passed = ExecuteWithRetries(reader, cfg, parameters, out resultMessage);
|
|
resultMessage = reader.Name + ": " + resultMessage;
|
|
}
|
|
|
|
messages.Add(resultMessage);
|
|
|
|
if (meterResult != null)
|
|
{
|
|
meterResult.RegReaderType = (int)RegisterReaderType.DataStream;
|
|
meterResult.TestDone = true;
|
|
meterResult.Passed = passed;
|
|
}
|
|
}
|
|
|
|
if (testResult != null)
|
|
{
|
|
testResult.EndTime = DateTime.Now;
|
|
testResult.TestDone = true;
|
|
testResult.Remark = string.Join("; ", messages);
|
|
}
|
|
|
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
|
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, testResult));
|
|
allResults.Info(TestResult2CsvLine(test.Name, 0));
|
|
|
|
return new List<Event> { Event.Done };
|
|
}
|
|
|
|
private static bool ExecuteWithRetries(
|
|
AllyMeterReader reader,
|
|
TestMethodCfg cfg,
|
|
TestMethodParams parameters,
|
|
out string resultMessage)
|
|
{
|
|
Exception lastException = null;
|
|
int attempts = Math.Max(1, cfg.MaxAttempts);
|
|
|
|
for (int attempt = 1; attempt <= attempts; attempt++)
|
|
{
|
|
try
|
|
{
|
|
bool passed = ExecuteOnce(reader, cfg, parameters, out resultMessage);
|
|
if (!passed)
|
|
return false;
|
|
if (attempt > 1)
|
|
resultMessage += " (attempt " + attempt + ")";
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lastException = ex;
|
|
if (attempt < attempts && cfg.DelayBetweenAttemptsMs > 0)
|
|
Thread.Sleep(cfg.DelayBetweenAttemptsMs);
|
|
}
|
|
}
|
|
|
|
resultMessage = lastException == null
|
|
? "ALLY command failed."
|
|
: "ALLY command failed after " + attempts + " attempts: " + lastException.Message;
|
|
return false;
|
|
}
|
|
|
|
private static bool ExecuteOnce(
|
|
AllyMeterReader reader,
|
|
TestMethodCfg cfg,
|
|
TestMethodParams parameters,
|
|
out string resultMessage)
|
|
{
|
|
AllyCalibrationActivity activity;
|
|
if (!AllyCalibrationActivityNames.TryParse(parameters.Activity, out activity))
|
|
throw new InvalidOperationException("Unknown ALLY calibration activity: " + parameters.Activity);
|
|
|
|
int timeout = cfg.CommandTimeoutMs;
|
|
switch (activity)
|
|
{
|
|
case AllyCalibrationActivity.ReadSerialNumber:
|
|
string serialNumber = reader.ReadSerialNumber(timeout);
|
|
if (string.IsNullOrWhiteSpace(serialNumber))
|
|
throw new FormatException("ALLY serial number response is empty.");
|
|
resultMessage = "SerialNumber=" + serialNumber;
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.ReadVersionAndType:
|
|
AllyVersionInfo version = reader.ReadVersionAndType(timeout);
|
|
bool deviceTypeOk = string.Equals(
|
|
version.DeviceType,
|
|
cfg.ExpectedDeviceType,
|
|
StringComparison.OrdinalIgnoreCase);
|
|
bool firmwareOk = string.IsNullOrWhiteSpace(cfg.ExpectedFirmwareVersion) ||
|
|
string.Equals(
|
|
version.FirmwareVersion,
|
|
cfg.ExpectedFirmwareVersion,
|
|
StringComparison.OrdinalIgnoreCase);
|
|
resultMessage = "Version=" + version +
|
|
", DeviceType=" + (deviceTypeOk ? "OK" : "NOK") +
|
|
", Firmware=" + (firmwareOk ? "OK" : "NOK");
|
|
return deviceTypeOk && firmwareOk;
|
|
|
|
case AllyCalibrationActivity.ReadSystemTime:
|
|
DateTime systemTime = reader.ReadSystemTimeUtc(timeout);
|
|
resultMessage = "SystemTimeUtc=" + systemTime.ToString("O");
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.ReadRebootCount:
|
|
byte rebootCount = reader.ReadRebootCount(timeout);
|
|
resultMessage = "RebootCount=" + rebootCount;
|
|
return rebootCount == 0;
|
|
|
|
case AllyCalibrationActivity.OpenValve:
|
|
reader.OpenValve(timeout);
|
|
resultMessage = "Valve=open";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.DisableSpreadSpectrum:
|
|
reader.SetSpreadSpectrum(false, timeout);
|
|
resultMessage = "SpreadSpectrum=disabled";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.SetInitialMeterMode:
|
|
reader.SetMeterMode(InitialMeterMode, timeout);
|
|
resultMessage = "MeterMode=0x09";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.TurnDiagnosticLedOn:
|
|
reader.SetDiagnosticLed(DiagnosticLedCalibrationMode, timeout);
|
|
resultMessage = "DiagnosticLED=0xC2";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.ResetCalibrationFactor:
|
|
double resetFactor = reader.ResetCalibrationFactor(timeout);
|
|
resultMessage = "ResetCalibrationFactor=" + resetFactor.ToString("F2") + "%";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.ReadCalibrationFactor:
|
|
double currentFactor = reader.ReadCalibrationFactor(timeout);
|
|
bool factorMatches = !reader.ExpectedCalibrationFactorPercent.HasValue ||
|
|
Math.Abs(currentFactor - reader.ExpectedCalibrationFactorPercent.Value) <= 0.05D;
|
|
resultMessage = "CalibrationFactor=" + currentFactor.ToString("F3") + "%";
|
|
return factorMatches;
|
|
|
|
case AllyCalibrationActivity.SetCalibrationMagneticTamperProfile:
|
|
reader.SetMagneticTamperProfile(AllyMagneticTamperProfile.Calibration, timeout);
|
|
resultMessage = "MagneticTamperProfile=calibration";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.TurnDiagnosticLedOff:
|
|
reader.SetDiagnosticLed(0x00, timeout);
|
|
resultMessage = "DiagnosticLED=off";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.SetActiveMeterMode:
|
|
reader.SetMeterMode(ActiveMeterMode, timeout);
|
|
resultMessage = "MeterMode=active";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.EnableSpreadSpectrum:
|
|
reader.SetSpreadSpectrum(true, timeout);
|
|
resultMessage = "SpreadSpectrum=enabled";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.SetDefaultMagneticTamperProfile:
|
|
reader.SetMagneticTamperProfile(AllyMagneticTamperProfile.FirmwareDefaults, timeout);
|
|
resultMessage = "MagneticTamperProfile=firmware defaults";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.WriteCalibrationFactor:
|
|
reader.SetCalibrationFactor(parameters.CalibrationFactorPercent, timeout);
|
|
resultMessage = "CalibrationFactorWritten=" +
|
|
parameters.CalibrationFactorPercent.ToString("F3") + "%";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.WriteDisplayVolume:
|
|
reader.SetDisplayVolume(DisplayVolume, timeout);
|
|
resultMessage = "DisplayVolume=" + DisplayVolume;
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.SetLcdTimeout:
|
|
reader.SetLcdTimeout(LcdTimeoutSeconds, timeout);
|
|
resultMessage = "LcdTimeout=30s";
|
|
return true;
|
|
|
|
case AllyCalibrationActivity.StartOffsetLearning:
|
|
reader.StartOffsetLearning(
|
|
OffsetLearningSamples,
|
|
OffsetLearningDelaySeconds,
|
|
timeout);
|
|
resultMessage = "OffsetLearning=1000 samples, 1s delay";
|
|
return true;
|
|
|
|
default:
|
|
throw new InvalidOperationException("Unsupported ALLY calibration activity.");
|
|
}
|
|
}
|
|
}
|
|
}
|