Implement OptoTelegramRaw class for processing diagnostic LED state data and refine Opto communication logic: update RadioService, SmartReader, and OptoHeadTest. Optimize serial communication and LED state handling.

This commit is contained in:
Michal Buzik 2026-02-12 09:45:03 +01:00
parent c57652a22f
commit 5fd68c624d
29 changed files with 1639 additions and 204 deletions

View File

@ -1,5 +1,3 @@
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
{
public static class Constants

View File

@ -86,9 +86,9 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProto
public IperlHatFrameBuilder AddDiagnosticLedState(DiagnosticLedState state)
{
_commandBytes.Add((byte)ProtocolCommand.DeviceSpecific);
_commandBytes.Add((byte)ProtocolDeviceSubCommand.SetDiagnosticLEDState);
_commandBytes.Add((byte)state);
RequestResponse(true);
AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState);
AddPayload((byte)state);
return this;
}

View File

@ -39,6 +39,9 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
/// </summary>
public abstract class DiagnosticLedData
{
public abstract int GetByteCount();
/// <summary>
/// Raw diagnostic LED line exactly as received from the meter,
/// including checksum and CRLF.

View File

@ -0,0 +1,37 @@
using System;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
{
public static class DiagnosticLedFrameSpec
{
public static int GetExpectedAsciiLength(DiagnosticLedState state)
{
switch (state)
{
case DiagnosticLedState.State1: return 33;
case DiagnosticLedState.State2: return 48;
case DiagnosticLedState.State3: return 50;
case DiagnosticLedState.State4: return 84;
case DiagnosticLedState.State5: return 89;
case DiagnosticLedState.State6: return 112;
case DiagnosticLedState.State7: return 139;
default: throw new ArgumentOutOfRangeException(nameof(state));
}
}
public static int GetExpectedFieldCount(DiagnosticLedState state)
{
switch (state)
{
case DiagnosticLedState.State1: return 6;
case DiagnosticLedState.State2: return 9;
case DiagnosticLedState.State3: return 9;
case DiagnosticLedState.State4: return 15;
case DiagnosticLedState.State5: return 16;
case DiagnosticLedState.State6: return 21;
case DiagnosticLedState.State7: return 26;
default: throw new ArgumentOutOfRangeException(nameof(state));
}
}
}
}

View File

@ -41,5 +41,18 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
{
return $"DiagnosticLedState1Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc ss
/// Chars total = 26
/// Tabs = 5
/// CRLF = 2
/// Total bytes = 33
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 33;
}
}
}

View File

@ -72,6 +72,19 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
{
return $"DiagnosticLedState2Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, LcdVolume={LcdVolume}, MeterState={MeterState}, IsLowFlowCutoff={IsLowFlowCutoff}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc gggggggg mm ff ss
/// Chars total = 38
/// Tabs = 8
/// CRLF = 2
/// Total bytes = 48
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 48;
}
}
}

View File

@ -72,5 +72,18 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
{
return $"DiagnosticLedState3Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb ff ss
/// Chars total = 40
/// Tabs = 8
/// CRLF = 2
/// Total bytes = 50
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 50;
}
}
}

View File

@ -73,6 +73,19 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
{
return $"DiagnosticLedState4Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff gggg hhhh cccc nnnn qq ss
/// Chars total = 68
/// Tabs = 14
/// CRLF = 2
/// Total bytes = 84
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 84;
}
}
}

View File

@ -93,6 +93,19 @@ public sealed class DiagnosticLedState5Data : DiagnosticLedData
{
return $"DiagnosticLedState5Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}, WaterImpedance={WaterImpedance}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff iiii ss
/// Chars total = 72
/// Tabs = 15
/// CRLF = 2
/// Total bytes = 89
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 89;
}
}
}

View File

@ -135,6 +135,18 @@ public sealed class DiagnosticLedState6Data : DiagnosticLedData
return $"DiagnosticLedState6Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState0={AsicState0}, WaterImpedance={WaterImpedance}, SpikeDetection={SpikeDetection}, PipeStatus={PipeStatus}, LcdVolume={LcdVolume}, AsicState1={AsicState1}";
}
/// <summary>
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff iiii rrrr pp ll dddddddd oo ss
/// Chars total = 90
/// Tabs = 20
/// CRLF = 2
/// Total bytes = 112
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 112;
}
}
}

View File

@ -137,6 +137,19 @@ public sealed class DiagnosticLedState7Data : DiagnosticLedData
{
return $"DiagnosticLedState7Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState0={AsicState0}, WaterImpedance={WaterImpedance}, ElectrodeDeltaMv={ElectrodeDeltaMv}, SpikeDetection={SpikeDetection}, PipeStatus={PipeStatus}, LcdVolume={LcdVolume}, AsicState1={AsicState1}, RawAdcBeforeOffset={RawAdcBeforeOffset}, DetrendedAdc={DetrendedAdc}, ImaginaryWaterImpedance={ImaginaryWaterImpedance}, ElectrodeVoltageNoise={ElectrodeVoltageNoise}, AdcOffsetLearningStatus={AdcOffsetLearningStatus}";
}
/// <summary>
/// Format:
/// Chars total = 112
/// Tabs = 25
/// CRLF = 2
/// Total bytes = 139
/// </summary>
/// <returns> Total bytes</returns>
public override int GetByteCount()
{
return 139;
}
}
}

View File

@ -2,16 +2,12 @@ using System;
using System.IO.Ports;
using Common;
using log4net;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
{
public class OptoHeadTest
public class OptoHeadTest : IDisposable
{
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
@ -25,35 +21,34 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
.WithDataBits(8)
.WithParity(Parity.None)
.WithStopBits(StopBits.One)
.WithTimeouts(2000, 2000)
.WithTimeouts(4000, 2000)
.BuildAndConnect();
}
internal static string ReadRequest_PCB(ISmartReader iHead)
public void CloseConnection()
{
byte[] frame = new IperlHatFrameBuilder()
.RequestResponse(true)
.AddCommand(ProtocolCommand.ViewFactoryId)
.BuildBytes();
if (serialDriver != null)
serialDriver.CloseConnection();
}
public static string ReadRequest_PCB(ISmartReader iHead)
{
if (iHead.DebugLevel == DebugMode.Simulate)
{
return "-OK Simulated response-";
}
string serialNo = null;
try
{
if (iHead != null)
{
if (serialDriver != null)
serialDriver = BuildConnection(iHead);
if (serialDriver == null)
serialDriver = BuildConnection(iHead);
RadioService headService = new RadioService(serialDriver);
serialNo = headService.ReadRequest_PCB(iHead);
string serialNo = headService.ReadRequest_PCB(iHead);
return serialNo;
}
}
@ -65,39 +60,24 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
return "";
}
public static string SetTestMode(ISmartReader aISmartReader)
public static string SetTestMode(ISmartReader iHead)
{
//Set LED to state 1
byte[] request = new TouchReadFrameBuilder()
.RequestResponse(true)
.AddDiagnosticLedState(DiagnosticLedState.State1)
.BuildBytes();
if (aISmartReader.DebugLevel == DebugMode.Simulate)
if (iHead.DebugLevel == DebugMode.Simulate)
{
return "-OK Simulated response-";
}
string serialNo = null;
try
{
if (aISmartReader != null)
if (iHead != null)
{
var driver = new SerialDriverBuilder()
.WithPort($"COM{aISmartReader.RfidComPortNr}")
.WithBaudRate(57600)
.WithDataBits(8)
.WithParity(Parity.None)
.WithStopBits(StopBits.Two)
.WithTimeouts(1000, 1000)
.BuildAndConnect();
if (serialDriver == null)
serialDriver = BuildConnection(iHead);
RadioService headService = new RadioService(driver);
serialNo = headService.SetTestMode(aISmartReader);
//correct or incorrect response
//okResponse, errorResponse
return serialNo;
RadioService headService = new RadioService(serialDriver);
string answer = headService.SetTestMode(iHead);
return answer;
}
}
catch (Exception ex)
@ -108,38 +88,23 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
return "";
}
public static string SetActiveMode(ISmartReader aISmartReader)
public static string SetActiveMode(ISmartReader iHead)
{
//Set LED to state 1
byte[] request = new TouchReadFrameBuilder()
.RequestResponse(true)
.AddDiagnosticLedState(DiagnosticLedState.StateOFF)
.BuildBytes();
if (aISmartReader.DebugLevel == DebugMode.Simulate)
if (iHead.DebugLevel == DebugMode.Simulate)
{
return "-OK Simulated response-";
}
string serialNo = null;
try
{
if (aISmartReader != null)
if (iHead != null)
{
var driver = new SerialDriverBuilder()
.WithPort($"COM{aISmartReader.RfidComPortNr}")
.WithBaudRate(57600)
.WithDataBits(8)
.WithParity(Parity.None)
.WithStopBits(StopBits.Two)
.WithTimeouts(1000, 1000)
.BuildAndConnect();
if (serialDriver == null)
serialDriver = BuildConnection(iHead);
RadioService headService = new RadioService(driver);
serialNo = headService.SetTestMode(aISmartReader);
//correct or incorrect response
//okResponse, errorResponse
return serialNo;
RadioService headService = new RadioService(serialDriver);
string answer = headService.SetActiveMode(iHead);
return answer;
}
}
catch (Exception ex)
@ -149,5 +114,10 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
return "";
}
public void Dispose()
{
CloseConnection();
}
}
}

View File

@ -36,13 +36,13 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
.BuildBytes();
byte[] rawData = serialDriver.SendAndWait(request, 1000);
byte[] rawData = serialDriver.SendAndWait(request, 10000);
if (rawData == null)
return null;
// parse rawData
var parser = new TouchReadFrameParser();
TouchReadResponse decoded = parser.Parse(rawData);
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
if (decoded.IsOk)
{
return decoded.GetAsciiPayload();
@ -58,10 +58,9 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
serialDriver.Open();
}
//Set LED to state 1
byte[] request = new TouchReadFrameBuilder()
.RequestResponse(true)
.AddDiagnosticLedState(DiagnosticLedState.State1)
//Set LED to state 4
byte[] request = new IperlHatFrameBuilder()
.AddDiagnosticLedState(DiagnosticLedState.State4)
.BuildBytes();
byte[] rawData = serialDriver.SendAndWait(request, 1000);
@ -70,19 +69,19 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
// parse rawData
var parser = new TouchReadFrameParser();
TouchReadResponse decoded = parser.Parse(rawData);
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
if (decoded.IsOk)
{
string asciiPayload = decoded.GetAsciiPayload();
//correct or incorrect response
//okResponse, errorResponse
return asciiPayload;
return "Set Test Mode - OK";
}
return null;
return "Set Test Mode - FAILED";
}
@ -99,8 +98,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
}
//Set LED to state 1
byte[] request = new TouchReadFrameBuilder()
.RequestResponse(true)
byte[] request = new IperlHatFrameBuilder()
.AddDiagnosticLedState(DiagnosticLedState.StateOFF)
.BuildBytes();
@ -109,22 +107,16 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
return null;
// parse rawData
var parser = new TouchReadFrameParser();
TouchReadResponse decoded = parser.Parse(rawData);
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
if (decoded.IsOk)
{
string asciiPayload = decoded.GetAsciiPayload();
//correct or incorrect response
//okResponse, errorResponse
return asciiPayload;
return "Set Active Mode - OK";
}
return null;
return "Set Active Mode - FAILED";
}
}
}

View File

@ -5,16 +5,18 @@ using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using FluentNHibernate.Conventions;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
{
public class SerialDriver : IDisposable
{
public string ErrorMessage { get; private set; }
public Collection<byte> SerialPortReadBuffer = new Collection<byte>();
private List<byte> SerialPortReadBuffer = new List<byte>();
private SerialPort _serialPort;
private readonly List<byte[]> _binMessages = new List<byte[]>();
private readonly List<byte> _binMessages = new List<byte>();
private bool _isReading;
// Stored configuration (used by Builder)
@ -178,7 +180,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
public byte[] GetRawData()
{
return _binMessages.Count > 0 ? _binMessages[0] : null;
return _binMessages.ToArray();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
@ -189,22 +191,67 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
try
{
Thread.Sleep(50);
Thread.Sleep(5);
SerialPortReadBuffer = new Collection<byte>();
while (_serialPort.BytesToRead > 0)
if (!SerialPortReadBuffer.IsEmpty())
{
SerialPortReadBuffer.Add((byte)_serialPort.ReadByte());
SerialPortReadBuffer.Clear();
}
int iWordCounter = 0;
bool isStart = false;
bool isQuestion = false;
int iLength = 0;
while (true)//_serialPort.BytesToRead > 0
{
byte readByte = (byte)_serialPort.ReadByte();
//I have START
if (readByte == C4.IperlHatProtocol.Constants.Start)
{
iWordCounter++;
isStart = true;
}
// I have QUESTION
if (readByte == C4.IperlHatProtocol.Constants.Question)
{
iWordCounter++;
isQuestion = true;
}
//I count length from start
if (iWordCounter > 0)
iWordCounter++;
if (iWordCounter > 0)
{
//Store byte to data
SerialPortReadBuffer.Add(readByte);
}
// we have length
if (iLength == 0 && isStart && SerialPortReadBuffer.Count > 2 )
{
iLength = (int)SerialPortReadBuffer[2];
}
//If we have enough bytes
if (isStart && iLength > 0 && SerialPortReadBuffer.Count >= iLength)
{
break;
}
//if we read END
if (isQuestion && readByte == C4.IperlHatProtocol.Constants.End)
{
break;
}
}
if (SerialPortReadBuffer.Count > 0)
{
_binMessages.Add(SerialPortReadBuffer.ToArray());
_binMessages.AddRange(SerialPortReadBuffer.ToArray());
_responseReceived.Set();
}
}
catch
catch (TimeoutException te)
{
// Ignore shutdown race conditions
}
@ -234,7 +281,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
#endregion
public void Dispose()
{
CloseConnection();

View File

@ -0,0 +1,160 @@
using System;
using System.Globalization;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
{
public enum OptoTelegramFlags : byte
{
OK = 0,
OK_TestStart,
OK_TestEnd,
InvalidTelegram, /// Wrong telegram format of checksum error
SyncError,
}
public class OptoTelegramRaw
{
private DiagnosticLedState4Data data;
private static CultureInfo culture;
///
/// Strobed value
///
public static decimal TestStartTimestampDec;
///
/// Stored values
///
public OptoTelegramFlags Flags;
public DateTime DateTime; /// From PC
public float RefFlow; /// [m3/h]
public int Counter;
public Int16 FlowRaw;
public UInt32 VolumeRaw;
public Int64 VolumeRawExt;
public UInt32 Timestamp;
public Int64 TimestampExt;
///
/// Calculated values
///
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
public double Volume(double scalingFactor) { return 0.0000625 * scalingFactor * (double)VolumeRawExt; }
public decimal TimestampDec() { return (decimal)TimestampExt / (decimal)8192; }
public double VolumeDelta(double scalingFactor,OptoTelegramRaw previous) { return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor); }
public decimal TimeDelta() { return TimestampDec() - TestStartTimestampDec; }
public string Label()
{
if (Flags == OptoTelegramFlags.OK_TestStart) return "#### start test ####";
else if (Flags == OptoTelegramFlags.OK_TestEnd) return "#### end of test ####";
else return string.Empty;
}
static OptoTelegramRaw()
{
culture = CultureInfo.CreateSpecificCulture("DE"); /// This is to use comma as decimal number separator
}
public OptoTelegramRaw()
{
}
public void UpdateFromSmart(DiagnosticLedState4Data data,int counter, float refFlow, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast)
{
DateTime = DateTime.Now;
Counter = counter;
RefFlow = refFlow;
FlowRaw = data.RawFlow;
VolumeRaw = data.RawVolume;
Timestamp = data.AsicTimestamp;
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
{
VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
}
else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
{
VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
///
/// Cope with 'Timestamp' overflow
///
uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
{
TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
}
else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
{
TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
}
public void SetFlags(OptoTelegramFlags flags)
{
this.Flags = flags;
}
public string ToString(double scalingFactor, OptoTelegramRaw previous)
{
if (Flags == OptoTelegramFlags.SyncError)
{
return "Sychronization error";
}
else if (Flags == OptoTelegramFlags.InvalidTelegram)
{
return "Invalid telegram";
}
else /// if (flags == OptoTelegramFlags.OK / OptoTelegramFlags.OK_TestStart / OptoTelegramFlags.OK_TestEnd)
{
return string.Format("{0}:{1}:{2}.{3}\t{4} :\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}",
DateTime.Hour.ToString("D2"),
DateTime.Minute.ToString("D2"),
DateTime.Second.ToString("D2"),
DateTime.Millisecond.ToString("D4"),
Counter,
FlowRaw.ToString("X4"),
VolumeRaw.ToString("X6"),
Timestamp.ToString("X8"),
Flow(scalingFactor).ToString("F2", culture),
Volume(scalingFactor).ToString("F4", culture),
TimestampDec().ToString("F4", culture),
(RefFlow * 1000).ToString("F2", culture),
VolumeDelta(scalingFactor, previous).ToString("F4", culture),
TimeDelta().ToString("F3", culture),
scalingFactor.ToString("F1", culture),
Label());
}
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Common;
using Common.Iperl;
@ -11,6 +12,9 @@ using NHibernate;
using Sensus.iPerl.NfcHandler;
using TBF.Rig.Generic;
using TBF.Rig.GenericDevices;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger;
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
using CalibrationStruct = TBF.Rig.RegisterReaders.CommonRR.IPerl.communication.CalibrationStruct;
@ -318,6 +322,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
OptoTelegramRaw[] optoData;
int optoDataCount;
DiagnosticLedParser parser = new DiagnosticLedParser(DiagnosticLedState.State4);
/// Real opto deta count, can be larger then optoData.Length
///
@ -388,7 +393,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
/// Check whether head is connected, working
try
{
OpenOptoSerialPort($"COM{_iPerlCfg.OptoComPortNr}", 9600, Parity.None, 8, StopBits.One, Handshake.None);
OpenOptoSerialPort($"COM{_iPerlCfg.OptoComPortNr}", 38400, Parity.None, 8, StopBits.One, Handshake.None);
CloseOptoSerialPort();
log.FatalFormat($"{Name} initialized: {this}");
}
@ -839,12 +844,6 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
/// <summary>
/// Reads opto-datastream via serial port. Invoked from RunDeviceBefore()
///
/// Telegram description:
/// AAAAAA[tab]BBBB[tab]CCCC[tab]DDDDDD[tab]EEEE[tab]FFFFFFFF[tab]GG[cr][lf] (42 bytes)
/// Example:
/// FFFFFE 51EA 0000 65324E 0087 F6319DFF 86
/// FFDD3A 51F9 0000 65324E 0088 F631A60B 45
/// ...
/// </summary>
/// <param name="optoState">OptoState.Read or OptoState.Flush</param>
void ReadOptoData(DataStreamState optoState)
@ -852,91 +851,64 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
if (optoSerialPort is null) return;
lock (this)
{
int nrBytes = optoSerialPort.BytesToRead;
if (nrBytes > 0)
{
char[] buffer = new char[nrBytes];
optoSerialPort.Read(buffer, 0, nrBytes);
string received = new string(buffer);
string allRcvd = partOfTelegram + received;
string line = optoSerialPort.ReadLine(); // string
byte[] bytes = optoSerialPort.Encoding.GetBytes(line);
while (true)
Console.WriteLine("RX ← " + HexFormatter.ToSerialHex(bytes));
try
{
int pos = allRcvd.IndexOf("\r\n");
/// CR+LF found
if (optoState == DataStreamState.ProcessAndSave)
{
DiagnosticLedState4Data data = (DiagnosticLedState4Data)parser.ParseLine(line, false);
int bufferIx = BufferIdx(optoDataCount);
if (pos < 0)
{
/// No CR+LF found, wait for more characters in the next invocation
partOfTelegram = allRcvd;
return;
}
else
{
/// CR+LF found
if (optoState == DataStreamState.ProcessAndSave)
if (synchronized)
{
int bufferIx = BufferIdx(optoDataCount);
optoData[bufferIx].Counter = optoDataCount;
optoData[bufferIx].SetFlags(OptoTelegramFlags.SyncError);
}
if (pos < OptoTelegramRaw.Length - 2)
{
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
allRcvd = allRcvd.Substring(pos + 2);
if (synchronized)
{
optoData[bufferIx].Counter = optoDataCount;
optoData[bufferIx].SetFlags(OptoTelegramFlags.SyncError);
}
if (data != null)
{
synchronized = true;
}
else if (optoData[bufferIx].UpdateFromString(
allRcvd.Substring(pos - OptoTelegramRaw.Length + 2),
optoDataCount,
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val),
ref volumeRawExtLast, ref timestampExtLast))
{
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) && the telegram is OK
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
OptoTelegramReceived(optoDataCount, synchronized2, volumeRawExtLast, timestampExtLast);
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
else
{
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) but the telgram was not OK
optoData[bufferIx].Counter = optoDataCount;
optoDataCount++;
allRcvd = allRcvd.Substring(pos + 2);
}
optoData[bufferIx].UpdateFromSmart(data, optoDataCount,
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val), ref volumeRawExtLast,
ref timestampExtLast);
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) && the telegram is OK
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
OptoTelegramReceived(optoDataCount, true, volumeRawExtLast,
timestampExtLast);
}
else
{
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) but the telgram was not OK
optoData[bufferIx].Counter = optoDataCount;
optoDataCount++;
}
else /// optoState == OptoState.Flush
optoDataCount++;
}
else /// optoState == OptoState.Flush
{
DiagnosticLedState4Data data = (DiagnosticLedState4Data)parser.ParseLine(line, false);
{
if (pos < OptoTelegramRaw.Length - 2)
{
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
allRcvd = allRcvd.Substring(pos + 2);
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegram.Length - 2)
else if (toBeFlushed.UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2),
0,
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val),
ref volumeRawExtLast, ref timestampExtLast))
{
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
else
{
allRcvd = allRcvd.Substring(pos + 2);
}
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
}
}
}
catch (Exception e)
{
}
//OnOptoReceived(this, new OptoReceivedEventArgs(s));
}
@ -947,19 +919,19 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
}
}
public string ReadOptoData()
{
if (optoSerialPort is null) return "";
string received = ".";
lock (this)
{
int nrBytes = optoSerialPort.BytesToRead;
if (nrBytes > 0)
{
char[] buffer = new char[nrBytes];
optoSerialPort.Read(buffer, 0, nrBytes);
received = new string(buffer);
}
string line = optoSerialPort.ReadLine(); // string
byte[] bytes = optoSerialPort.Encoding.GetBytes(line);
received = HexFormatter.ToSerialHex(bytes);
Console.WriteLine("RX ← " + received);
}
return received;
@ -1020,7 +992,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
if ((startIx > 0) && (startIx < StartOptoDataCount) && (optoData[startIx].Flags == OptoTelegramFlags.OK))
{
optoData[startIx].Flags = OptoTelegramFlags.OK_TestStart;
OptoTelegramRaw.TestStartTimestampDec = optoData[startIx].TimestampDec();
Common.Iperl.OptoTelegramRaw.TestStartTimestampDec = optoData[startIx].TimestampDec();
}
else
{
@ -1029,7 +1001,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
if (optoData[ix].Flags == OptoTelegramFlags.OK)
{
/// This is the first correct opto-telegram received
OptoTelegramRaw.TestStartTimestampDec = optoData[ix].TimestampDec();
Common.Iperl.OptoTelegramRaw.TestStartTimestampDec = optoData[ix].TimestampDec();
break;
}
}
@ -1177,6 +1149,8 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
CloseOptoSerialPort();
optoSerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBit);
optoSerialPort.Handshake = handshake;
optoSerialPort.NewLine = "\r\n";
optoSerialPort.Encoding = Encoding.ASCII; // or UTF8 if needed
optoSerialPort.Open();
log.FatalFormat($"{Name} OptoPort opened: {this}");
}
@ -1212,7 +1186,7 @@ namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
{
try
{
OpenOptoSerialPort($"COM{_iPerlCfg.OptoComPortNr}", 9600, Parity.None, 8, StopBits.One, Handshake.None);
OpenOptoSerialPort($"COM{_iPerlCfg.OptoComPortNr}", 38400, Parity.None, 8, StopBits.One, Handshake.None);
}
catch (Exception)
{

View File

@ -11,6 +11,7 @@ using TBF.Rig.RegisterReaders.CommonRR.IPerl;
using TBF.Rig.TestMethods.SmartTest;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public class TestMethodCfg : ComponentCfgBase, ITestMethodCfg

View File

@ -9,6 +9,7 @@ using log4net;
using log4net.Repository.Hierarchy;
using TBF.Rig.Generic;
using TBF.Rig.Sequences;
using TBF.Rig.TestMethods.SmartTest;
namespace TBF.Rig
{
@ -191,6 +192,7 @@ namespace TBF.Rig
new TestMethods.FlyingStartTankCollection.Compound.Factory(),
new TestMethods.GrabImage.Factory(),
new TestMethods.iPerlCommunication.TestMethodFactory(), /// iPerlCommunication
new TestMethods.SmartTest.TestMethodFactory(), /// Smart Meter Tests
new TestMethods.LeakTest.Factory(),
new TestMethods.LiveStream.Factory(),
new TestMethods.ManualEntry.Factory(),

View File

@ -0,0 +1,85 @@
///
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using System.IO.Ports;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
namespace TBF.Rig.TestMethods.SmartTest
{
public class TestMethodCfg : ComponentCfgBase, ITestMethodCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestMethodCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new TestMethodCfgCtrl(); }
public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; }
public override IParamsProvider CreateTestParamsProvider() { return new iPerlCommunicationParams(true); }
public override IParamsProvider GetUITestParamsProvider(Test test)
{
return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
}
/// Private parameterless constructor invoked by all other (public) constructors
TestMethodCfg()
{
Name = "iPerlCommunication";
ParentName = string.Empty;
CommTimeout = 1800; /// ms
MaxCommRetries = 4;
WaitTimeAfterFailure = 2200;
PassThroughWaitTime = 1500;
NrThreads = 2; /// 1, 2 or 4 threads
IperlCheckErrorsToStop = 10;
MciTimeoutMs = 4000; // ms, NFC interface
BaudRate = 57600; // NFC Interface
DataBits = 8; // NFC Interface
ParityBit = Parity.None; // NFC Interface
StopBits = StopBits.Two; // NFC Interface
TestParams = CreateTestParamsProvider() as iPerlCommunicationParams;
}
public TestMethodCfg(IComponentFactory factory)
: this()
{
this.Factory = factory;
}
public string ToString(int i)
{
return string.Format("Name={0}, CommTimeout={1}, MaxRetries={2}, NrThreads={3}", Name, CommTimeout, MaxCommRetries, NrThreads);
}
public int CommTimeout { get; set; }
public int DelayBetweenRetries { get; set; }
public int MaxCommRetries { get; set; }
public int WaitTimeAfterFailure { get; set; }
public int PassThroughWaitTime { get; set; }
public int NrThreads { get; set; }
public int IperlCheckErrorsToStop { get; set; }
public int MciTimeoutMs { get; set; }
public int BaudRate { get; set; }
public int DataBits { get; set; }
public Parity ParityBit { get; set; }
public StopBits StopBits { get; set; }
/// <summary> Test parameters </summary>
[XmlIgnore]
public iPerlCommunicationParams TestParams;
public bool UseWebService { get; set; }
public string BaseUrl { get; set; }
public string RelativeUrl { get; set; }
}
}

View File

@ -0,0 +1,975 @@
///
/// Copyright (c) 2015-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing;
using Common;
using Config.Entities;
using log4net;
using RestClient;
using Results.Entities;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.Rig.Sequences;
using TBF.Rig.TestMethods.iPerlCommunication;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
using TBF.UiBridge;
using iPerlCommunicationParams = TBF.Rig.TestMethods.iPerlCommunication.iPerlCommunicationParams;
/// Point definition
namespace TBF.Rig.TestMethods.SmartTest
{
public class iPerlCommunicationSeq : SequenceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationSeq));
public const string Q2correctedFromCmd = "Q2 corrected from ";
public const string StrictQ2ErrorCheckStr = "Strict Q2 error check ";
public const string Q2correctionCheckCmd = "Q2 correction check ";
public const string IperlCheckCmd = "iPERL_check ";
public const string SimulateCmd = "simulate ";
System.Windows.Forms.Form modelessDlg;
///
delegate void SmartCommunicationFormDlgt(iPerlCommunicationSeq myRef, TestMethod method, Test test, ITestParams testParams);
///
void OpenIPerlCommForm(iPerlCommunicationSeq myRef, TestMethod method, Test test, ITestParams testParams)
{
myRef.modelessDlg = new SmartCommunicationForm(method, test, testParams);
myRef.modelessDlg.Show();
}
void CloseIPerlCommForm()
{
UiBridge.Bridge.OnCloseModelessForm(this, null);
modelessDlg = null;
}
/// <summary>
/// Flying start mass collection method sequence
/// </summary>
/// <param name="test">Test entity</param>
/// <returns>
/// Event.Done . . . . . . . OK
/// Event.UiCmdStop . . . . Stopped by the user using the on-screen button STOP
/// Event.OpArgumentError . Target flow is out of range
/// Event.Error . . . . . . Unspecified error
/// </returns>
public IList<Event> Execute(Test test, int repetitionNr, TestMethod method, ITestParams testParams)
{
TestMethodCfg cfgIPerl = method.Cfg as TestMethodCfg;
IList<Event> e; /// Events from currently running operations
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
modelessDlg = null;
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, false);
string cmd;
// Normalize activity once (also prevents NullReferenceException on .ToLower()).
var activity = testParams?.Activity;
var activityLower = activity?.ToLowerInvariant();
if (!string.IsNullOrEmpty(activityLower) &&
activityLower.Equals(cmd = iPerlCommunicationConstants.GetDefaultQ2CorrectionsStr.ToLower()))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
/// Get 'wmType' from IperlHead procedure parameters
int wmType = 0;
#if IPERL
/*foreach (var wm in ProcessData.BatchRslts.Batch.WaterMeters)
{
if (wm != null && !wm.Disabled && wm.WMTypeId() > 0)
{
wmType = wm.WMTypeId();
break;
}
}*/
#endif
//
// if (cfgIPerl.UseWebService)
// {
// IsQ2PreCorrectionCalculated = GetQ2PreCorrectionsOrBackups(cfgIPerl, wmType, out CalculatedQ2PreCorrectionLR, out CalculatedQ2PreCorrectionRL);
// }
/// Generate test results
Results.Entities.TestRslt tstRslt = BatchRslts.GetTestRslt(test.Name, 0);
if (tstRslt != null)
{
tstRslt.StartTime = DateTime.Now;
tstRslt.TestDone = true;
foreach (var wm in BatchRslts.Batch.WaterMeters)
{
if (!wm.Disabled)
{
foreach(var mtr in wm.MeterTestRslts)
{
if (mtr.TestRslt == tstRslt)
{
mtr.Passed = /*!cfgIPerl.UseWebService ||*/ IsQ2PreCorrectionCalculated;
mtr.TestDone = true;
break;
}
}
}
}
}
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
return new List<Event> { Event.Done };
}
else if (!string.IsNullOrEmpty(activityLower) &&
activityLower.Contains(cmd = Q2correctedFromCmd.ToLowerInvariant()))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
string fromTestName = (args.Length >= 1) ? args[0] : string.Empty;
bool isPlus = (args.Length >= 2) ? args[1].ToLower().Contains("plus") : false;
MakeQ2CorrectedFrom(test.Name, fromTestName, isPlus);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
return new List<Event> { Event.Done };
}
else if (!string.IsNullOrEmpty(activityLower) &&
activityLower.Contains(cmd = StrictQ2ErrorCheckStr.ToLowerInvariant()))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
string fromTestName = testParams.Activity.Substring(cmd.Length);
StrictQ2ErrorCheck(test.Name, fromTestName);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
return new List<Event> { Event.Done };
}
else if (!string.IsNullOrEmpty(activityLower) &&
activityLower.Contains(cmd = Q2correctionCheckCmd.ToLowerInvariant()))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
string[] testNames = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
if (testNames.Length >= 2)
{
CheckQ2Correction(test.Name, testNames[0], testNames[1]);
}
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
return new List<Event> { Event.Done };
}
else if (!string.IsNullOrEmpty(activityLower) &&
activityLower.Contains(cmd = IperlCheckCmd.ToLowerInvariant()))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
//int maxTestIndex = (ProcessData.BenchInfo is TBF.Rig.DataContainer.BenchInfo.Component)
// ? (ProcessData.BenchInfo as TBF.Rig.DataContainer.BenchInfo.Component).MaxTestIndex
// : int.MaxValue;
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, 0);
if (tstRslt != null)
{
tstRslt.StartTime = DateTime.Now;
int wrongMetersCount = 0;
string message = string.Empty;
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
{
Results.Entities.WaterMeter wm = BatchRslts.Batch.WaterMeters[i];
Results.Entities.MeterTestRslt mtr = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, i, CompoundMeterId.Single);
///// Reference to iPerl water meter or null:
//TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerlHead = ((sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
// ? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
// : null;
if ((wm != null) && (mtr != null))
{
int errorIndicators = 0;
bool anyErrorOfThisMeter = false;
foreach (var arg in args)
{
#if TURA_SPECIAL
if (arg.ToLower() == "q2factors")
{
if ((wm.ProdQ2CorrRL != wm.Q2CorrRL) || (wm.ProdQ2CorrLR != wm.Q2CorrLR))
{
anyErrorOfThisMeter = true;
message += string.Format("Q2 korekčné faktory vodomera {0} nesedia{1}", wm.WMPosition, Environment.NewLine);
errorIndicators |= (int)ErrorFlagMask.E26; /// Q2 correction factors not valid
}
}
#endif
if (arg.ToLower() == "direction")
{
//if (wm.Pruefindex > maxTestIndex)
//{
// anyErrorOfThisMeter = true;
// message += string.Format("Príliš veľa opakovaní testu vodomera {0}{1}", wm.WMPosition, Environment.NewLine);
// errorIndicators |= (int)ErrorFlagMask.E27; /// Wrong direction (positive/negative counting)
//}
}
if (arg.ToLower() == "prevworkstep")
{
if (wm.LastRecordIsNok)
{
wm.ErrorFlags |= (int)ErrorFlagMask.E28; /// Set E28
}
if ((wm.ErrorFlags & (int)ErrorFlagMask.E28) != 0)
{
anyErrorOfThisMeter = true;
message += string.Format("iPerl{0} : Predchádzajúci krok nebol zaznamenaný{1}", wm.WMPosition, Environment.NewLine);
errorIndicators |= (int)ErrorFlagMask.E28; /// Previous workstep missing or NOK (production tracing)
}
}
}
mtr.TestDone = true;
mtr.ErrorIndicators = errorIndicators;
///
if (anyErrorOfThisMeter)
{
/// This iPerl check did not pass
mtr.Passed = false;
wrongMetersCount++;
}
else
{
/// Check passed OK
mtr.Passed = true;
}
}
}
tstRslt.EndTime = DateTime.Now;
tstRslt.TestDone = true;
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, tstRslt));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
if (wrongMetersCount >= cfgIPerl.IperlCheckErrorsToStop)
{
State.Create("iPerlCommunicationSeq : Show check result")
.AddOperation(new Operations.LargeMessageBoxOp(message))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
}
while (!e.Contains(Event.Continue) && !e.Contains(Event.Abort));
if (e.Contains(Event.Abort))
{
Bridge.OnError(this, string.Format("Niečo nie je v poriadku !"));
return new List<Event> { Event.UiCmdStop };
}
}
}
return new List<Event> { Event.Done };
}
else if (!string.IsNullOrEmpty(activity) &&
activity.Contains(cmd = SimulateCmd))
{
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
if (testParams.Activity.ToLower().Contains("q3")) MakeSimulated(test, 1, 0, -0.5f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q2") MakeSimulated(test, 1, 0, 0.5f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q1") MakeSimulated(test, 1, 0, -5.1f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound ok") MakeSimulatedCompound(test, 1, 0, 0.7f, 1.0f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound nok") MakeSimulatedCompound(test, 1, 0, 4.7f, 0.9f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound rise") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.0f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound fall") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.9f);
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "iperls")
{
string[] pcbNrs = new string[] { "831232435539", "831232435562", "831232435587",
"831232432141", "831232432497", "831232763641" };
TestRslt tstRslt = 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 = DateTime.Now;
tstRslt.FlowSetTime = 0;
tstRslt.MassOfEvapWater = 0;
tstRslt.TestTime = 1;
for (int i = 0; i < BatchRslts.Batch.WaterMeters.Count; i++)
{
MeterTestRslt meterRslt =
BatchRslts.GetMeterTestRslt(test.Name, i, CompoundMeterId.Single);
if (meterRslt != null)
{
meterRslt.WaterMeter.SerialNr = pcbNrs[i % pcbNrs.Length];
meterRslt.Passed = true;
meterRslt.TestDone = true;
}
//if (iperlHeads[i] != null)
//{
// iperlHeads[i].CommFailed = iperlHeads[i].Disabled = false;
// iperlHeads[i].SerialNr = pcbNrs[i % pcbNrs.Length];
//}
}
}
}
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(Common.Utils.GetTestName(test.Name, 1, 1), 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
//------------------------------------------------
Bridge.OnActivity(this, testParams.Activity);
//------------------------------------------------
State.Create(string.Format("iPerlCommunicationSeq : {0}", testParams.Activity))
.AddOperation(checkUiOp)
.EnterState();
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e))
{
return new List<Event> { Event.UiCmdStop };
}
}
else
{
///
/// Show the modeless dialog with error indication
///
///
// IMPORTANT:
// Avoid Control.Invoke(Delegate, object[]) because it tries to convert each argument
// to the delegate parameter types at runtime (and currently it expects a different TestMethod type).
//Program.MainWnd.Invoke((Action)(() => OpenIPerlCommForm(this, method, test, testParams)));
Program.MainWnd.Invoke(new SmartCommunicationFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed
bool completed = false;
State.Create("iPerlCommunicationSeq : Wait until the entry form is closed")
.AddOperation(checkUiOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
stopPressed = TestAndLogUiCmdStop(test, e);
completed = (modelessDlg is GenericDevices.IHasCompleted)
&& (modelessDlg as GenericDevices.IHasCompleted).Completed;
}
while (!stopPressed && !completed);
if (stopPressed)
{
CloseIPerlCommForm();
return new List<Event> { Event.UiCmdStop };
}
else
{
TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(test.Name, Progress.Completed));
}
/// Test 'Quit'
modelessDlg = null; /// Modeless dialog is closed now
}
return new List<Event> { Event.Done };
}
/// <summary>
/// Read default Q2 correction factors from a REST service (= Web service).
/// </summary>
/// <param name="cfgIPerl">iPerlCommunication component configuration</param>
/// <param name="wmType">Water meter type (WZ Typ)</param>
/// <param name="q2PreCorrectionLR">Default Q2 correction LR</param>
/// <param name="q2PreCorrectionRL">Default Q2 correction RL</param>
/// <returns>true when successful</returns>
static bool ReadCorrectionsFromWebService(TestMethodCfg_IPerl cfgIPerl, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL)
{
if (wmType == 0)
{
/// No REST service call when wmType == 0, factors are 0
q2PreCorrectionLR = 0;
q2PreCorrectionRL = 0;
return true;
}
try
{
GetQ2PreCorrectionClient client = new GetQ2PreCorrectionClient(cfgIPerl.BaseUrl);
client.GetToken("ReadUser", "sensus", "https://deluh1web03.world.fluidtechnology.net/SensusCore/api/v1/Locations/1/Login2").Wait();
Q2PreCorrection response = client.GetQ2Correction(string.Format(cfgIPerl.RelativeUrl, wmType)).Result;
if (response != null && response.AreDataCalculated)
{
q2PreCorrectionLR = response.CorrLR;
q2PreCorrectionRL = response.CorrRL;
log.WarnFormat("Q2 corrections from a REST client for WM Type = {0} are: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
return true;
}
else
{
log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}", wmType);
q2PreCorrectionLR = 0;
q2PreCorrectionRL = 0;
return false;
}
}
catch (Exception exc)
{
log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}: {1}", wmType, exc.Message);
q2PreCorrectionLR = 0;
q2PreCorrectionRL = 0;
return false;
}
}
/// <summary>
/// Obtain Q2 correction factors from a REST service or from local settings (stored backup values)
/// </summary>
/// <param name="cfgIPerl">iPerlCommunication component configuration</param>
/// <param name="wmType">Water meter type (WZ Typ)</param>
/// <param name="q2PreCorrectionLR">Default Q2 correction LR</param>
/// <param name="q2PreCorrectionRL">Default Q2 correction RL</param>
/// <returns>true when successful</returns>
public static bool GetQ2PreCorrectionsOrBackups(TestMethodCfg_IPerl cfgIPerl, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL)
{
/// Get Q2 pre-correction values from REST service
bool restOK = ReadCorrectionsFromWebService(cfgIPerl, wmType, out q2PreCorrectionLR, out q2PreCorrectionRL);
/// Store / load Q2 pre-correction values
Point storedValue;
if (restOK)
{
/// Q2 pre-correction values were successfully obtained from a REST service for the specified wmType
if (!Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue))
{
/// No Q2 pre-correction values in the dictionary for the specified wmType => save them
Program.LocalSettings.Q2PreCorrections.Add(wmType, new Point(q2PreCorrectionLR, q2PreCorrectionRL));
log.WarnFormat("Q2 corrections added to dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
}
else if (storedValue.X != q2PreCorrectionLR || storedValue.Y != q2PreCorrectionRL)
{
/// Different Q2 pre-correction values in the dictionary for the specified wmType => overwrite them with ones from the REST service
Program.LocalSettings.Q2PreCorrections[wmType] = new Point(q2PreCorrectionLR, q2PreCorrectionRL);
log.WarnFormat("Q2 corrections modified in dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
}
else
{
/// Q2 pre-correction values in the dictionary are the same and were not changed
log.WarnFormat("Q2 corrections in dictionary for WM Type = {0} are the same and were not changed", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
}
}
else
{
/// No Q2 pre-correction values from a REST service => read the dictionary
if (Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue))
{
/// Q2 pre-correction values successfully read from the dictionary
q2PreCorrectionLR = storedValue.X;
q2PreCorrectionRL = storedValue.Y;
log.WarnFormat("Q2 corrections loaded from dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
}
else
{
/// Q2 pre-correction values not found in the dictionary => use zeros
q2PreCorrectionLR = 0;
q2PreCorrectionRL = 0;
log.ErrorFormat("Q2 corrections not found in the dictionary for WM Type = {0}, using zeros", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
/// Everything failed => using zero values
return false;
}
}
/// Q2 pre-corections were obtained from REST service or stored backup values were used
return true;
}
/// <summary>
/// Virtually apply Q2 correction to a test used for the correction calculation.
/// </summary>
/// <param name="testName">This test name</param>
/// <param name="oriTestRslt">Name of Q2 test done before Q2 correction (Q2adj)</param>
/// <remarks>Assuming this test does not have multiple parts (part = 0)</remarks>
void MakeQ2CorrectedFrom(string testName, string oriTestName, bool isPlus = false)
{
Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0);
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
if (oriTestRslt == null || tstRslt == null) return;
tstRslt.Components = oriTestRslt.Components;
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
tstRslt.AmbTempMean = oriTestRslt.AmbTempMean;
tstRslt.AmbTempStart = oriTestRslt.AmbTempStart;
tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd;
tstRslt.AmbTempMin = oriTestRslt.AmbTempMin;
tstRslt.AmbTempMax = oriTestRslt.AmbTempMax;
tstRslt.AmbPressMean = oriTestRslt.AmbPressMean;
tstRslt.AmbPressStart = oriTestRslt.AmbPressStart;
tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd;
tstRslt.AmbPressMin = oriTestRslt.AmbPressMin;
tstRslt.AmbPressMax = oriTestRslt.AmbPressMax;
tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean;
tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart;
tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd;
tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin;
tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax;
tstRslt.PressUpMean = oriTestRslt.PressUpMean;
tstRslt.PressUpStart = oriTestRslt.PressUpStart;
tstRslt.PressUpEnd = oriTestRslt.PressUpEnd;
tstRslt.PressUpMin = oriTestRslt.PressUpMin;
tstRslt.PressUpMax = oriTestRslt.PressUpMax;
tstRslt.PressDownMean = oriTestRslt.PressDownMean;
tstRslt.PressDownStart = oriTestRslt.PressDownStart;
tstRslt.PressDownEnd = oriTestRslt.PressDownEnd;
tstRslt.PressDownMin = oriTestRslt.PressDownMin;
tstRslt.PressDownMax = oriTestRslt.PressDownMax;
tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean;
tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart;
tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd;
tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin;
tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax;
tstRslt.ConductMean = oriTestRslt.ConductMean;
tstRslt.ConductStart = oriTestRslt.ConductStart;
tstRslt.ConductEnd = oriTestRslt.ConductEnd;
tstRslt.ConductMin = oriTestRslt.ConductMin;
tstRslt.ConductMax = oriTestRslt.ConductMax;
tstRslt.TempUpMean = oriTestRslt.TempUpMean;
tstRslt.TempUpStart = oriTestRslt.TempUpStart;
tstRslt.TempUpEnd = oriTestRslt.TempUpEnd;
tstRslt.TempUpMin = oriTestRslt.TempUpMin;
tstRslt.TempUpMax = oriTestRslt.TempUpMax;
tstRslt.TempDownMean = oriTestRslt.TempDownMean;
tstRslt.TempDownStart = oriTestRslt.TempDownStart;
tstRslt.TempDownEnd = oriTestRslt.TempDownEnd;
tstRslt.TempDownMin = oriTestRslt.TempDownMin;
tstRslt.TempDownMax = oriTestRslt.TempDownMax;
tstRslt.TempDivMean = oriTestRslt.TempDivMean;
tstRslt.TempDivStart = oriTestRslt.TempDivStart;
tstRslt.TempDivEnd = oriTestRslt.TempDivEnd;
tstRslt.TempDivMin = oriTestRslt.TempDivMin;
tstRslt.TempDivMax = oriTestRslt.TempDivMax;
tstRslt.DensityIn = oriTestRslt.DensityIn;
tstRslt.DensityLine = oriTestRslt.DensityLine;
tstRslt.DensityDiv = oriTestRslt.DensityDiv;
tstRslt.StartTime = oriTestRslt.StartTime;
tstRslt.EndTime = oriTestRslt.EndTime;
tstRslt.FlowSetTime = oriTestRslt.FlowSetTime;
tstRslt.TestTime = oriTestRslt.TestTime;
tstRslt.PulsesMaster = oriTestRslt.PulsesMaster;
tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw;
tstRslt.ConstMaster = oriTestRslt.ConstMaster;
tstRslt.MassStartRaw = oriTestRslt.MassStartRaw;
tstRslt.MassStart = oriTestRslt.MassStart;
tstRslt.MassEndRaw = oriTestRslt.MassEndRaw;
tstRslt.MassEnd = oriTestRslt.MassEnd;
tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater;
//tstRslt.FlowMass = oriTestRslt.FlowMass;
//tstRslt.FlowVolume = oriTestRslt.FlowVolume;
tstRslt.VolumeCTV = oriTestRslt.VolumeCTV;
tstRslt.VolumeMaster = oriTestRslt.VolumeMaster;
tstRslt.ErrorMaster = oriTestRslt.ErrorMaster;
tstRslt.FlowMean = oriTestRslt.FlowMean;
tstRslt.FlowMin = oriTestRslt.FlowMin;
tstRslt.FlowMax = oriTestRslt.FlowMax;
tstRslt.Custom1 = oriTestRslt.Custom1;
tstRslt.Custom2 = oriTestRslt.Custom2;
tstRslt.Custom3 = oriTestRslt.Custom3;
tstRslt.Custom4 = oriTestRslt.Custom4;
tstRslt.Custom5 = oriTestRslt.Custom5;
tstRslt.Custom6 = oriTestRslt.Custom6;
tstRslt.Custom7 = oriTestRslt.Custom7;
tstRslt.Custom8 = oriTestRslt.Custom8;
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
{
// Fix for CS7036: Added the missing 'meterId' argument to the GetMeterTestRslt method call.
var q3mtr = ProcessData.BatchRslts.GetMeterTestRslt("Q3", i, CompoundMeterId.SingleOrCompound);
double q3error = (q3mtr != null) ? q3mtr.Error : 0;
Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i, CompoundMeterId.SingleOrCompound);
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.SingleOrCompound);
/// Reference to iPerl water meter or null:
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
: null;
if (iPerl != null && meterRslt != null && oriMeterRslt != null)
{
#if ORACLE_DB
meterRslt.ErrorBC = oriMeterRslt.Error;
#endif
meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter;
meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster;
meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter;
meterRslt.VolumeRef = oriMeterRslt.VolumeRef;
meterRslt.TestTime = oriMeterRslt.TestTime;
if (q3error * oriMeterRslt.Error < 0)
{
/// iPerl with Q2 correction => generate an artificial error equal to +1/10 of the original one (relative to Q2 target error)
meterRslt.Error = 0.1 * oriMeterRslt.Error;
}
else
{
/// iPerl with Q2 correction => generate an artificial error equal to -1/10 of the original one (relative to Q2 target error)
meterRslt.Error = - 0.1 * oriMeterRslt.Error;
}
meterRslt.VolumeMeter = meterRslt.VolumeRef * (100.0 + meterRslt.Error) / 100.0;
double signature = (oriMeterRslt.VolumeEnd > oriMeterRslt.VolumeStart) ? (+1) : (-1);
meterRslt.VolumeStart = oriMeterRslt.VolumeStart;
meterRslt.VolumeEnd = meterRslt.VolumeStart + signature * meterRslt.VolumeMeter;
meterRslt.Passed = (meterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()
&& meterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
meterRslt.TestDone = true;
tstRslt.TestDone = true;
}
}
}
/// <summary>
/// Evaluate a given Q2 test result agains stricter error limits when Oruefindex == 1.
/// </summary>
/// <param name="testName">This test name</param>
/// <param name="oriTestRslt">Name of Q2 test done before Q2 correction (Q2adj)</param>
/// <remarks>Assuming this test does not have multiple parts (part = 0)</remarks>
void StrictQ2ErrorCheck(string testName, string oriTestName)
{
Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0);
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
if (oriTestRslt == null || tstRslt == null) return;
tstRslt.Components = oriTestRslt.Components;
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
tstRslt.AmbTempMean = oriTestRslt.AmbTempMean;
tstRslt.AmbTempStart = oriTestRslt.AmbTempStart;
tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd;
tstRslt.AmbTempMin = oriTestRslt.AmbTempMin;
tstRslt.AmbTempMax = oriTestRslt.AmbTempMax;
tstRslt.AmbPressMean = oriTestRslt.AmbPressMean;
tstRslt.AmbPressStart = oriTestRslt.AmbPressStart;
tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd;
tstRslt.AmbPressMin = oriTestRslt.AmbPressMin;
tstRslt.AmbPressMax = oriTestRslt.AmbPressMax;
tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean;
tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart;
tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd;
tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin;
tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax;
tstRslt.PressUpMean = oriTestRslt.PressUpMean;
tstRslt.PressUpStart = oriTestRslt.PressUpStart;
tstRslt.PressUpEnd = oriTestRslt.PressUpEnd;
tstRslt.PressUpMin = oriTestRslt.PressUpMin;
tstRslt.PressUpMax = oriTestRslt.PressUpMax;
tstRslt.PressDownMean = oriTestRslt.PressDownMean;
tstRslt.PressDownStart = oriTestRslt.PressDownStart;
tstRslt.PressDownEnd = oriTestRslt.PressDownEnd;
tstRslt.PressDownMin = oriTestRslt.PressDownMin;
tstRslt.PressDownMax = oriTestRslt.PressDownMax;
tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean;
tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart;
tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd;
tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin;
tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax;
tstRslt.ConductMean = oriTestRslt.ConductMean;
tstRslt.ConductStart = oriTestRslt.ConductStart;
tstRslt.ConductEnd = oriTestRslt.ConductEnd;
tstRslt.ConductMin = oriTestRslt.ConductMin;
tstRslt.ConductMax = oriTestRslt.ConductMax;
tstRslt.TempUpMean = oriTestRslt.TempUpMean;
tstRslt.TempUpStart = oriTestRslt.TempUpStart;
tstRslt.TempUpEnd = oriTestRslt.TempUpEnd;
tstRslt.TempUpMin = oriTestRslt.TempUpMin;
tstRslt.TempUpMax = oriTestRslt.TempUpMax;
tstRslt.TempDownMean = oriTestRslt.TempDownMean;
tstRslt.TempDownStart = oriTestRslt.TempDownStart;
tstRslt.TempDownEnd = oriTestRslt.TempDownEnd;
tstRslt.TempDownMin = oriTestRslt.TempDownMin;
tstRslt.TempDownMax = oriTestRslt.TempDownMax;
tstRslt.TempDivMean = oriTestRslt.TempDivMean;
tstRslt.TempDivStart = oriTestRslt.TempDivStart;
tstRslt.TempDivEnd = oriTestRslt.TempDivEnd;
tstRslt.TempDivMin = oriTestRslt.TempDivMin;
tstRslt.TempDivMax = oriTestRslt.TempDivMax;
tstRslt.DensityIn = oriTestRslt.DensityIn;
tstRslt.DensityLine = oriTestRslt.DensityLine;
tstRslt.DensityDiv = oriTestRslt.DensityDiv;
tstRslt.StartTime = oriTestRslt.StartTime;
tstRslt.EndTime = oriTestRslt.EndTime;
tstRslt.FlowSetTime = oriTestRslt.FlowSetTime;
tstRslt.TestTime = oriTestRslt.TestTime;
tstRslt.PulsesMaster = oriTestRslt.PulsesMaster;
tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw;
tstRslt.ConstMaster = oriTestRslt.ConstMaster;
tstRslt.MassStartRaw = oriTestRslt.MassStartRaw;
tstRslt.MassStart = oriTestRslt.MassStart;
tstRslt.MassEndRaw = oriTestRslt.MassEndRaw;
tstRslt.MassEnd = oriTestRslt.MassEnd;
tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater;
//tstRslt.FlowMass = oriTestRslt.FlowMass;
//tstRslt.FlowVolume = oriTestRslt.FlowVolume;
tstRslt.VolumeCTV = oriTestRslt.VolumeCTV;
tstRslt.VolumeMaster = oriTestRslt.VolumeMaster;
tstRslt.ErrorMaster = oriTestRslt.ErrorMaster;
tstRslt.FlowMean = oriTestRslt.FlowMean;
tstRslt.FlowMin = oriTestRslt.FlowMin;
tstRslt.FlowMax = oriTestRslt.FlowMax;
tstRslt.Custom1 = oriTestRslt.Custom1;
tstRslt.Custom2 = oriTestRslt.Custom2;
tstRslt.Custom3 = oriTestRslt.Custom3;
tstRslt.Custom4 = oriTestRslt.Custom4;
tstRslt.Custom5 = oriTestRslt.Custom5;
tstRslt.Custom6 = oriTestRslt.Custom6;
tstRslt.Custom7 = oriTestRslt.Custom7;
tstRslt.Custom8 = oriTestRslt.Custom8;
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
{
Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i, CompoundMeterId.Single);
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single);
/// Reference to iPerl water meter or null:
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
: null;
if (meterRslt != null && oriMeterRslt != null)
{
#if ORACLE_DB
meterRslt.ErrorBC = oriMeterRslt.Error;
#endif
meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter;
meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster;
meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter;
meterRslt.VolumeRef = oriMeterRslt.VolumeRef;
meterRslt.TestTime = oriMeterRslt.TestTime;
if (iPerl != null && ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
{
/// Either no iPerl head or no Q2 correction
meterRslt.Error = oriMeterRslt.Error;
meterRslt.VolumeMeter = oriMeterRslt.VolumeMeter;
meterRslt.VolumeStart = oriMeterRslt.VolumeStart;
meterRslt.VolumeEnd = oriMeterRslt.VolumeEnd;
#if ORACLE_DB
if ((ProcessData.BatchRslts.Batch.WaterMeters[i].Pruefindex % 100) == 1)
{
meterRslt.Passed = (oriMeterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()
&& oriMeterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
}
else
#endif
{
meterRslt.Passed = oriMeterRslt.Passed;
}
meterRslt.TestDone = true;
tstRslt.TestDone = true;
}
}
}
}
/// <summary>
/// Check results of 2 tests: before Q2 correction and after Q2 correction.
/// Evaluate whether Q2 correction works OK.
/// </summary>
/// <param name="testName">This test name</param>
/// <param name="testNameQ2bc">Name of Q2 test done before correction</param>
/// <param name="testNameQ2ac">Name of Q2 test done after correction</param>
/// <remarks>Assuming these tests do not have multiple parts (part = 0)</remarks>
void CheckQ2Correction(string testName, string testNameQ2bc, string testNameQ2ac)
{
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
Results.Entities.TestRslt testRsltQ2bc = ProcessData.BatchRslts.GetTestRslt(testNameQ2bc, 0);
Results.Entities.TestRslt testRsltQ2ac = ProcessData.BatchRslts.GetTestRslt(testNameQ2ac, 0);
if ((tstRslt == null) || (testRsltQ2bc == null) || (testRsltQ2ac == null)) return;
tstRslt.Components = testRsltQ2ac.Components;
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
tstRslt.AmbTempMean = testRsltQ2ac.AmbTempMean;
tstRslt.AmbTempStart = testRsltQ2ac.AmbTempStart;
tstRslt.AmbTempEnd = testRsltQ2ac.AmbTempEnd;
tstRslt.AmbTempMin = testRsltQ2ac.AmbTempMin;
tstRslt.AmbTempMax = testRsltQ2ac.AmbTempMax;
tstRslt.AmbPressMean = testRsltQ2ac.AmbPressMean;
tstRslt.AmbPressStart = testRsltQ2ac.AmbPressStart;
tstRslt.AmbPressEnd = testRsltQ2ac.AmbPressEnd;
tstRslt.AmbPressMin = testRsltQ2ac.AmbPressMin;
tstRslt.AmbPressMax = testRsltQ2ac.AmbPressMax;
tstRslt.AmbHumiMean = testRsltQ2ac.AmbHumiMean;
tstRslt.AmbHumiStart = testRsltQ2ac.AmbHumiStart;
tstRslt.AmbHumiEnd = testRsltQ2ac.AmbHumiEnd;
tstRslt.AmbHumiMin = testRsltQ2ac.AmbHumiMin;
tstRslt.AmbHumiMax = testRsltQ2ac.AmbHumiMax;
tstRslt.PressUpMean = testRsltQ2ac.PressUpMean;
tstRslt.PressUpStart = testRsltQ2ac.PressUpStart;
tstRslt.PressUpEnd = testRsltQ2ac.PressUpEnd;
tstRslt.PressUpMin = testRsltQ2ac.PressUpMin;
tstRslt.PressUpMax = testRsltQ2ac.PressUpMax;
tstRslt.PressDownMean = testRsltQ2ac.PressDownMean;
tstRslt.PressDownStart = testRsltQ2ac.PressDownStart;
tstRslt.PressDownEnd = testRsltQ2ac.PressDownEnd;
tstRslt.PressDownMin = testRsltQ2ac.PressDownMin;
tstRslt.PressDownMax = testRsltQ2ac.PressDownMax;
tstRslt.PressDeltaMean = testRsltQ2ac.PressDeltaMean;
tstRslt.PressDeltaStart = testRsltQ2ac.PressDeltaStart;
tstRslt.PressDeltaEnd = testRsltQ2ac.PressDeltaEnd;
tstRslt.PressDeltaMin = testRsltQ2ac.PressDeltaMin;
tstRslt.PressDeltaMax = testRsltQ2ac.PressDeltaMax;
tstRslt.ConductMean = testRsltQ2ac.ConductMean;
tstRslt.ConductStart = testRsltQ2ac.ConductStart;
tstRslt.ConductEnd = testRsltQ2ac.ConductEnd;
tstRslt.ConductMin = testRsltQ2ac.ConductMin;
tstRslt.ConductMax = testRsltQ2ac.ConductMax;
tstRslt.TempUpMean = testRsltQ2ac.TempUpMean;
tstRslt.TempUpStart = testRsltQ2ac.TempUpStart;
tstRslt.TempUpEnd = testRsltQ2ac.TempUpEnd;
tstRslt.TempUpMin = testRsltQ2ac.TempUpMin;
tstRslt.TempUpMax = testRsltQ2ac.TempUpMax;
tstRslt.TempDownMean = testRsltQ2ac.TempDownMean;
tstRslt.TempDownStart = testRsltQ2ac.TempDownStart;
tstRslt.TempDownEnd = testRsltQ2ac.TempDownEnd;
tstRslt.TempDownMin = testRsltQ2ac.TempDownMin;
tstRslt.TempDownMax = testRsltQ2ac.TempDownMax;
tstRslt.TempDivMean = testRsltQ2ac.TempDivMean;
tstRslt.TempDivStart = testRsltQ2ac.TempDivStart;
tstRslt.TempDivEnd = testRsltQ2ac.TempDivEnd;
tstRslt.TempDivMin = testRsltQ2ac.TempDivMin;
tstRslt.TempDivMax = testRsltQ2ac.TempDivMax;
tstRslt.DensityIn = testRsltQ2ac.DensityIn;
tstRslt.DensityLine = testRsltQ2ac.DensityLine;
tstRslt.DensityDiv = testRsltQ2ac.DensityDiv;
tstRslt.StartTime = testRsltQ2ac.StartTime;
tstRslt.EndTime = testRsltQ2ac.EndTime;
tstRslt.FlowSetTime = testRsltQ2ac.FlowSetTime;
tstRslt.TestTime = testRsltQ2ac.TestTime;
tstRslt.PulsesMaster = testRsltQ2ac.PulsesMaster;
tstRslt.ConstMasterRaw = testRsltQ2ac.ConstMasterRaw;
tstRslt.ConstMaster = testRsltQ2ac.ConstMaster;
tstRslt.MassStartRaw = testRsltQ2ac.MassStartRaw;
tstRslt.MassStart = testRsltQ2ac.MassStart;
tstRslt.MassEndRaw = testRsltQ2ac.MassEndRaw;
tstRslt.MassEnd = testRsltQ2ac.MassEnd;
tstRslt.MassOfEvapWater = testRsltQ2ac.MassOfEvapWater;
//tstRslt.FlowMass = testRsltQ2ac.FlowMass;
//tstRslt.FlowVolume = testRsltQ2ac.FlowVolume;
tstRslt.VolumeCTV = testRsltQ2ac.VolumeCTV;
tstRslt.VolumeMaster = testRsltQ2ac.VolumeMaster;
tstRslt.ErrorMaster = testRsltQ2ac.ErrorMaster;
tstRslt.FlowMean = testRsltQ2ac.FlowMean;
tstRslt.FlowMin = testRsltQ2ac.FlowMin;
tstRslt.FlowMax = testRsltQ2ac.FlowMax;
tstRslt.Custom1 = testRsltQ2ac.Custom1;
tstRslt.Custom2 = testRsltQ2ac.Custom2;
tstRslt.Custom3 = testRsltQ2ac.Custom3;
tstRslt.Custom4 = testRsltQ2ac.Custom4;
tstRslt.Custom5 = testRsltQ2ac.Custom5;
tstRslt.Custom6 = testRsltQ2ac.Custom6;
tstRslt.Custom7 = testRsltQ2ac.Custom7;
tstRslt.Custom8 = testRsltQ2ac.Custom8;
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
{
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single);
Results.Entities.MeterTestRslt meterRsltQ2bc = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2bc, i, CompoundMeterId.Single);
Results.Entities.MeterTestRslt meterRsltQ2ac = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2ac, i, CompoundMeterId.Single);
if ((meterRslt != null) && (meterRsltQ2bc != null) && (meterRsltQ2ac != null))
{
meterRslt.PulsesMeter = meterRsltQ2ac.PulsesMeter;
meterRslt.PulsesMaster = meterRsltQ2ac.PulsesMaster;
meterRslt.PulsesPerLiter = meterRsltQ2ac.PulsesPerLiter;
meterRslt.VolumeRef = meterRsltQ2ac.VolumeRef;
meterRslt.TestTime = meterRsltQ2ac.TestTime;
meterRslt.VolumeStart = meterRsltQ2ac.VolumeStart;
meterRslt.VolumeEnd = meterRsltQ2ac.VolumeEnd;
meterRslt.VolumeMeter = meterRsltQ2ac.VolumeMeter;
meterRslt.Error = meterRsltQ2ac.Error;
meterRslt.TestDone = meterRsltQ2ac.TestDone;
tstRslt.TestDone = true;
if (((meterRsltQ2bc.Error < -0.51) && (meterRsltQ2ac.Error < meterRsltQ2bc.Error)) ||
((meterRsltQ2bc.Error > +0.51) && (meterRsltQ2ac.Error > meterRsltQ2bc.Error)))
{
meterRslt.Passed = false; /// Q2 correction check failed
}
else
{
meterRslt.Passed = true; /// Q2 correction check passed
}
}
}
}
}
}

View File

@ -158,6 +158,22 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
continue;
}
if (smartHead is RegisterReaders.iPerlASICReader.implementations.SmartReader smartReaderASIC )
{
if (correctionsList.Any(x => x is IPerlASICCorrections))
continue;
//(SmartCommunicationForm parent, ISmartTestMethod testMethod, ITestMethodCfg cfg, IList<Config.Entities.Test> tests, IList<ITestParams> multiTestParams)
correctionsList.Add(new IPerlASICCorrections(this,/*log, rfidDataLogger,*/ componentBase, cfg, tests, multiTestParams));
continue;
}
if (smartHead is RegisterReaders.IPerlReader.implementations.SmartReader smartiPerlReader )
{
if (correctionsList.Any(x => x is IPerlCorrections))
continue;
correctionsList.Add(new IPerlCorrections( this,componentBase, cfg, tests, multiTestParams));
continue;
}
throw new Exception("Unknown smart head type");
}
catch (Exception e)
@ -325,11 +341,11 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
{
checkBoxesEditMode = false;
ITestMethodCfg cfg = (componentBase as ITestMethodCfg);
ITestMethodCfg cfg = (componentBase.Cfg as ITestMethodCfg);
ISmartTestMethod smartTestMethod = componentBase as ISmartTestMethod;
//TODO get corrections based on defined meter
_corrections = GetNewCorrectionList(smartTestMethod, smartTestMethod.TestMethodCfg, tests, multiTestParams);
_corrections = GetNewCorrectionList(smartTestMethod, cfg, tests, multiTestParams);
InitializeMeterTypeItems();
UpdateHeads();
@ -410,7 +426,10 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
if (waterMeterPositions0 == null) waterMeterPositions0 = new List<int>();
//iperlHeads = ProcessData.SmartHeadsUni;
string comparedTypeReader = SelectedTypeReader;
if (string.IsNullOrEmpty(SelectedTypeReader))
//TODO BUMI solve problem with init first
//ProcessData.SmartHeadsUni?.ForEach( head => iperlHeads.Add(head));
if (string.IsNullOrEmpty(SelectedTypeReader) )
{
comparedTypeReader = ProcessData.SmartHeadsUni?.First()?.GetType().Name;
}
@ -418,12 +437,13 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
ICorrections corre = null;
foreach (ICorrections correction in _corrections)
{
if (correction.TypeIdentificatorName() == SelectedTypeReader)
if (correction.TypeIdentificatorName() == comparedTypeReader)
{
corre = correction;
break;
}
}
if (corre == null) corre = _corrections.First();
if (corre != null)
{
@ -700,7 +720,11 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
//currentGroup++;
int wtId = 0;
foreach (var wt in Correction.GetAllThreads())
var threads = Correction?.GetAllThreads();
if (threads == null)
return;
foreach (var wt in threads)
{
wt.Start(new Boxes.IntBox(wtId++)); /// Start worker threads !!!
}
@ -860,6 +884,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45,
checkBoxImage46, checkBoxImage47, checkBoxImage48,
};
if (ckbIndex == null) return;
for (int i = 0; i < 48; i++)
{
int wmNr0 = ckbIndex[i];

View File

@ -15,11 +15,15 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
public class iPerlCommunicationParams : TestParamsBase, IParamsProvider, ITestParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(iPerlCommunicationParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public string Activity; /// Communication activity
public bool SimultWithPrevious;
public bool SimultWithNext;
public override XmlSerializer GetSerializer()
{
return Serializer;
}
public override void InitializeAll()
{

View File

@ -384,7 +384,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
int[] ckbIndex,
bool[] ckbState, IList<ISmartReader> iperlHeads, int textBoxesCount, bool checkBoxesEditMode)
{
if (iperlHeads == null)
if (iperlHeads == null || iperlHeads.Count == 0)
{
for (int i = 0; i < textBoxesCount; i++)
{
@ -401,7 +401,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
{
labels[i].Visible = counters[i].Visible = messages[i].Visible = checkBoxes[i].Visible = true;
IperlHead iperlHead = iperlHeads[i] as IperlHead;
if (!checkBoxesEditMode && (iperlHead == null || iperlHead.Disabled))
{
@ -416,6 +416,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = true;
messages[i].Text = "---";
}
}
}

View File

@ -1254,6 +1254,7 @@
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\DiagnosticLedParser.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\DiagnosticLedState.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\parserer\DiagnosticLedData.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\parserer\DiagnosticLedFrameSpec.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\parserer\DiagnosticLedState1Data.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\parserer\DiagnosticLedState2Data.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\diagnosticLed\parserer\DiagnosticLedState3Data.cs" />
@ -1295,6 +1296,7 @@
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\Utils\SerialDriver.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\Factory.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\IPerlASICImplHeadTestCtrl.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\OptoTelegramRaw.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\SmartReader.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IPerlCfg.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IPerlUniCfgCtrl.cs">
@ -1677,8 +1679,10 @@
</Compile>
<Compile Include="Rig\TestMethods\SmartMeterFlyingStartMassCollection\Factory.cs" />
<Compile Include="Rig\TestMethods\SmartMeterFlyingStartMassCollection\TestMethodCfg.cs" />
<Compile Include="Rig\TestMethods\SmartTest\iPerlCommunicationSeq.cs" />
<Compile Include="Rig\TestMethods\SmartTest\SequenceConditionOp.cs" />
<Compile Include="Rig\TestMethods\SmartTest\TestMethod.cs" />
<Compile Include="Rig\TestMethods\SmartTest\TestMethodCfg.cs" />
<Compile Include="Rig\TestMethods\SmartTest\TestMethodCfgCtrl.cs">
<SubType>UserControl</SubType>
</Compile>

View File

@ -157,7 +157,23 @@ namespace TBFTests.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHat
Console.WriteLine(log);
Console.WriteLine(@"Raw: < {0} >", HexFormatter.ToSerialHex(request));
}
[TestMethod]
public void AddDiagnosticLedState()
{
// ----------- Arrange -----------
byte[] request = new IperlHatFrameBuilder()
.AddDiagnosticLedState(DiagnosticLedState.State4)
.BuildBytes();
byte[] expected = HexFormatter.HexStringToByteArray("53 57 07 FD 60 04 0D");
CollectionAssert.AreEqual(expected, request);
string log = IperlHatLogger.DescribeTx(request);
Console.WriteLine(log);
Console.WriteLine(@"Raw: < {0} >", HexFormatter.ToSerialHex(request));
}
}
}

View File

@ -451,8 +451,14 @@ namespace TBFTests.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHat
/// This test work only if Opto data are active
/// Use OptoCommunicationON_ReadOpto_CommunicatonOFF() test method
/// </summary>
//[TestMethod]
//[TestCategory("Hardware")]
[TestMethod]
[TestCategory("Hardware")]
public void Serial_OptoRawSniff_Standalone()
{
Serial_OptoRawSniff();
}
//method test connection to optho head
private void Serial_OptoRawSniff()
{
using (var port = new SerialPort("COM4", BaudRateOpto, Parity.None, 8, StopBits.One))

View File

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TBF.Rig.RegisterReaders.iPerlASICReader.communication;
using TBF.Rig.RegisterReaders.iPerlASICReader.implementations;
namespace TBFTests.Rig.RegisterReaders.iPerlASICReader.communication
{
[TestClass]
[TestSubject(typeof(OptoHeadTest))]
public class OptoHeadTestTest
{
[TestMethod]
public void ReadRequest_PCB_Test()
{
OptoHeadTest optoHeadTest = new OptoHeadTest();
//TBF.Rig.Generic.IComponentCfg cfg = optoHeadTest.;
SmartReader iPerlAsicReader = new SmartReader();
OptoHeadTest.ReadRequest_PCB(iPerlAsicReader);
}
}
}

View File

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TBF.Rig.RegisterReaders.iPerlASICReader.implementations;
namespace TBFTests.Rig.RegisterReaders.iPerlASICReader.implementations
{
[TestClass]
[TestSubject(typeof(IPerlASICImplHeadTestCtrl))]
public class IPerlASICImplHeadTestCtrlTest
{
[TestMethod]
public void CommandTestButtonClick_Operations_ReadPcbCmd()
{
}
}
}

View File

@ -112,6 +112,8 @@
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\led\TouchReadLedMessageTest.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\wiredProtocol\TouchReadBaudRateDetectionTests.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\wiredProtocol\TouchReadFrameBuilderTest.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\OptoHeadTestTest.cs" />
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\IPerlASICImplHeadTestCtrlTest.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunnerTest.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonReaderTest.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonReader\UniHeadTestCtrlTest.cs" />