A – Registration and execution - Register GenesisCommunication Factory in the component list. - Separate the Genesis form and sequence from iPerl communication. B – Communication activities - Restore initialization, connection, PCB reading, password and login. - Include grouped login, mode switching and disconnection. - Support processing up to 10 slots. C1 – Input calibration factors - Read three factors from Water meters / Text1–Text3. - Validate integer values in the range 1–65535. - Preserve the default of 15625 when all three fields are empty. D – Q3 calibration - Connect the Prepare Q3 → measurement → Write Q3 workflow. - Add channel processing to FlyingStart and FlyingStartMassCollection. - Reset previous measurement data and validate calculated factors. - Mark factors as stored only after StoreCalibration succeeds. E – Results and database - Store calibration factors separately for each meter and channel. - Add result entities, mappings and Q3 data. - Extend DB.cs / EnsureSchema to create and update the schema. - Preserve compatibility with the existing binary format. Validation: - Debug build and 18 tests passed. - Simulated communication runs follow the same activity sequence. - The complete Q3 workflow has not yet been verified on hardware. Known limitation: - An inherited mismatch in simulated responses and error propagation can produce an incorrect OK result; this change does not fix it.
236 lines
8.3 KiB
C#
236 lines
8.3 KiB
C#
///
|
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Common;
|
|
using Results.Entities;
|
|
|
|
namespace Results
|
|
{
|
|
public class BatchResults
|
|
{
|
|
public Batch Batch;
|
|
public int WMPositionsCount;
|
|
|
|
public IList<Entities.TestData> TestDataList;
|
|
public IList<Entities.Components> ComponentsList;
|
|
public IList<Entities.WaterMeterData> WaterMeterDataList;
|
|
|
|
|
|
/// <summary>
|
|
/// Parameterless constructor required for serialization
|
|
/// </summary>
|
|
public BatchResults()
|
|
{
|
|
TestDataList = new List<Entities.TestData>();
|
|
ComponentsList = new List<Entities.Components>();
|
|
WaterMeterDataList = new List<Entities.WaterMeterData>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor invoked by static BatchResults NewFromProcedure(...)
|
|
/// </summary>
|
|
/// <param name="wmPositionsCount">Watermeters count</param>
|
|
private BatchResults(int wmPositionsCount)
|
|
: this()
|
|
{
|
|
WMPositionsCount = wmPositionsCount;
|
|
}
|
|
|
|
|
|
public static BatchResults NewFromProcedure(int batchNr, int benchId, string benchName, string a1, string a2, string a3, string a4, string a5,
|
|
string user, int userNr, string programVer, Config.Entities.Procedure procedure,
|
|
WaterMeterData[] waterMeterDatas, int[] waterMeterParts,
|
|
string variant, string order, string workflow, string laserMarking,
|
|
double realDensity, double atTemperature, double buoyancy)
|
|
{
|
|
BatchResults d = new BatchResults(waterMeterDatas.Length);
|
|
int year = DateTime.Now.Year;
|
|
|
|
/// Create new batch
|
|
d.Batch = new Batch()
|
|
{
|
|
BatchNr = batchNr,
|
|
ProgramVersion = programVer,
|
|
TestBenchId = benchId,
|
|
TestBenchName = benchName,
|
|
Address1 = a1,
|
|
Address2 = a2,
|
|
Address3 = a3,
|
|
Address4 = a4,
|
|
Address5 = a5,
|
|
UserName = user,
|
|
UserNumber = userNr,
|
|
ProcedureName = procedure.Name,
|
|
ProcedureDescription = procedure.Description,
|
|
WatermetersStr = (variant != null) ? variant : string.Empty,
|
|
PurchaseOrder = order,
|
|
Workflow = workflow,
|
|
ProcedureRevision = procedure.Revision,
|
|
StartTime = DateTime.Now,
|
|
SampleDensity = realDensity,
|
|
SampleTemp = atTemperature,
|
|
Buoyancy = buoyancy,
|
|
Compound = (procedure.MetersKind == MetersKind.Combined),
|
|
#if HEAT_METERS
|
|
HeatMeter = (procedure.MetersKind == MetersKind.HeatMeter),
|
|
#endif
|
|
};
|
|
|
|
///
|
|
/// Add watermeter to an array, array index is WM position.
|
|
/// AddWaterMetersToBatch() has to be used before saving results.
|
|
///
|
|
for (int wmPos0 = 0; wmPos0 < d.WMPositionsCount; wmPos0++)
|
|
{
|
|
var wm = new WaterMeter()
|
|
{
|
|
Batch = d.Batch,
|
|
WMPosition = wmPos0 + 1,
|
|
YearOfProduction = year,
|
|
};
|
|
|
|
if (waterMeterDatas[wmPos0] != null)
|
|
{
|
|
wm.WaterMeterData = WaterMeterData.UpdateList(d.WaterMeterDataList, waterMeterDatas[wmPos0]);
|
|
}
|
|
else
|
|
{
|
|
wm.Disabled = true;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(order)) wm.PurchaseOrder = order;
|
|
if (!string.IsNullOrEmpty(laserMarking)) wm.Remark = laserMarking;
|
|
|
|
d.Batch.WaterMeters.Add(wm);
|
|
}
|
|
|
|
foreach (var ti in procedure.GetTestInstances())
|
|
{
|
|
TestData td = TestData.UpdateList(d.TestDataList, new TestData(ti.Test));
|
|
|
|
/// Create an empty test result and add it to the list
|
|
TestRslt tr = new TestRslt(d.Batch, td, ti.Test.Part, ti.Repetition);
|
|
d.Batch.TestRslts.Add(tr);
|
|
|
|
for (int i = 0; i < d.WMPositionsCount; i++)
|
|
{
|
|
if (!d.Batch.WaterMeters[i].Disabled && ti.Test.IsPartCompatible(waterMeterParts[i]))
|
|
{
|
|
///
|
|
/// Create empty watermeter test results and add them to the list and to dictionaries
|
|
///
|
|
IList<MeterTestRslt> wmtrs = d.Batch.WaterMeters[i].MeterTestRslts;
|
|
if (d.Batch.Compound)
|
|
{
|
|
/// Compound water meter
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.CompoundMain));
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.CompoundAux));
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.Compound));
|
|
}
|
|
else if (d.Batch.HeatMeter)
|
|
{
|
|
/// Heat meter
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.HeatMeterVolume));
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.HeatMeterEnergy));
|
|
}
|
|
else
|
|
{
|
|
/// Water meter
|
|
wmtrs.Add(new MeterTestRslt(d.Batch.WaterMeters[i], tr, CompoundMeterId.Single));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return d;
|
|
}
|
|
|
|
public static BatchResults FromBatch(Batch batch)
|
|
{
|
|
if (batch.WaterMeters == null || batch.WaterMeters.Count == 0) return null;
|
|
|
|
int wmPosMax = 0;
|
|
foreach (var wm in batch.WaterMeters) if (wm.WMPosition > wmPosMax) wmPosMax = wm.WMPosition;
|
|
|
|
BatchResults batchResults = new BatchResults(wmPosMax);
|
|
batchResults.Batch = batch;
|
|
/// Insert missing disabled water meters
|
|
for (int wmNr0 = 0; wmNr0 < wmPosMax; wmNr0++)
|
|
{
|
|
if (batch.WaterMeters[wmNr0].WMPosition > wmNr0 + 1)
|
|
{
|
|
batch.WaterMeters.Insert(wmNr0, new WaterMeter() { Batch = batch,
|
|
WaterMeterData = null,
|
|
WMPosition = wmNr0 + 1,
|
|
YearOfProduction = 0,
|
|
Disabled = true, });
|
|
}
|
|
}
|
|
|
|
return batchResults;
|
|
}
|
|
|
|
public TestRslt GetTestRslt(string name, int part)
|
|
{
|
|
return Batch.GetTestRslt(name, part);
|
|
}
|
|
|
|
public MeterTestRslt GetMeterTestRslt(string name, int wmNr0, CompoundMeterId meterId)
|
|
{
|
|
if (Batch.WaterMeters != null && Batch.WaterMeters.Count > wmNr0 && !Batch.WaterMeters[wmNr0].Disabled)
|
|
{
|
|
return Batch.WaterMeters[wmNr0].GetMeterTestRslt(name, meterId);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public MeterTestRslt GetEachMeterTestRslt(string name, int wmNr0, CompoundMeterId meterId)
|
|
{
|
|
if (Batch.WaterMeters != null && Batch.WaterMeters.Count > wmNr0)
|
|
{
|
|
return Batch.WaterMeters[wmNr0].GetMeterTestRslt(name, meterId);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns true when all tests were done
|
|
/// </summary>
|
|
/// <returns>true = all tests done</returns>
|
|
public bool AllTestsDone()
|
|
{
|
|
for (int wmNr0 = 0; wmNr0 < WMPositionsCount; wmNr0++)
|
|
{
|
|
if (Batch.WaterMeters != null && Batch.WaterMeters.Count > wmNr0 && !Batch.WaterMeters[wmNr0].Disabled)
|
|
{
|
|
foreach (var mtr in Batch.WaterMeters[wmNr0].MeterTestRslts)
|
|
{
|
|
if (mtr.Evaluate() && !mtr.TestDone) return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public virtual void WriteBinary(BinaryWriter writer)
|
|
{
|
|
Batch.WriteBinary(writer);
|
|
writer.Write(WMPositionsCount);
|
|
}
|
|
|
|
public virtual void ReadBinary(BinaryReader reader)
|
|
{
|
|
Batch = new Batch();
|
|
Batch.ReadBinary(reader);
|
|
WMPositionsCount = reader.ReadInt32();
|
|
}
|
|
}
|
|
}
|