common/Hardware/WaterMeter/Genesis/GenesisCore/_GenesisMeterCalibration.cs
2026-04-23 17:50:07 +02:00

240 lines
9.2 KiB
C#

using System;
using System.Linq;
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.Const;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.ProductionOrderCore.TestResults;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.Metrology.Measurements;
using Xylem.Common.Metrology.Measurements.Consts;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
{
public partial class GenesisMeter
{
/// <summary>
/// Calibration factors for all channels
/// </summary>
private readonly CalibFactor[] _calibFactor = new CalibFactor[MeterConfig.CalibChannels];
/// <summary>
/// Registers needed to store the calibration for the individual channel
/// </summary>
private readonly String[] _registersToStoreCalibFactor =
{
Register.Genesisflow.CalFactor1,
Register.Genesisflow.CalFactor2,
Register.Genesisflow.CalFactor3
};
/// <inheritdoc />
public void InitCalibration()
{
Logger.Info($"Slot:{Slot} - Init calibration and set calibration values of all channels to default");
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
{
_calibFactor[channel] = new CalibFactor(channel, _registersToStoreCalibFactor[channel]);
WriteRegister(_registersToStoreCalibFactor[channel],
_calibFactor[channel].GetMeterRawCalibFactorDefault(), checkRegister: true);
}
PreMeasurement();
}
/// <inheritdoc />
public void StartCalibration()
{
StartMeasurement();
}
/// <inheritdoc />
/// <summary>
/// Just stop recording without calculation
/// </summary>
public void StopCalibration()
{
StopMeasurement();
}
/// <inheritdoc />
public MeasurementStates GetCalibrationState()
{
return GetMeasurementState();
}
/// <inheritdoc />
public void BuildAndCheckCalibFactorsAllChannels(Double refVolumeCm, Double? refTimeS, Double reqDeviationPercent, Double maxCalibFactorTolerancePercent = MeterConfig.DefaultMaxCalibFactorTolerancePercent, int? testrunNr = null)
{
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
{
_calibFactor[channel] = new CalibFactor(channel, _registersToStoreCalibFactor[channel]);
}
foreach (var item in _listOfIMeasurement.Where(m => m.GetType() == typeof(CalibrationRecord)))
{
if (!(item is CalibrationMeasurement))
{
continue;
}
var calib = item as CalibrationMeasurement;
var channel = calib.GetChannel();
if (channel == 0 || channel > MeterConfig.CalibChannels)
{
var message = $"Slot:{Slot}, Channel:{channel} - Calibration channel out of range";
Logger.Warn(message);
throw new ApplicationException(message);
}
Logger.Info($"Slot:{Slot}, Channel:{channel} - Calculate Calibrationfactor Relative(RefVolumeCm:{refVolumeCm}, refTimeS:{refTimeS},reqDeviationPercent:{reqDeviationPercent})");
var calibFactorRel = calib.CalculateCalibFactorRel(refVolumeCm, refTimeS, reqDeviationPercent);
//if the null return indicates an invalid calibration factor the calibFactorX.IsCalculated remains false
if (null == calibFactorRel)
{
var message = $"Slot:{Slot}, Channel:{channel} - Calibration factor not calculated";
Logger.Warn(message);
throw new ApplicationException(message);
}
_calibFactor[channel - 1].BuildMeterCalibFactor(calibFactorRel.Value);
_calibFactor[channel - 1].IsCalculated = true;
Logger.Info($"Slot:{Slot}, Channel:{channel} - New calibration factor({_calibFactor[channel - 1].GetRelativeCalibFactor()}rel/{calibFactorRel})");
Logger.Info($"Slot:{Slot}, Channel:{channel} - Calc /{_calibFactor[channel - 1].GetMeterRawCalibFactor()} * {calibFactorRel.Value}) -> UInt16");
//Setup the required tolerance value to check against
//plus/minus x% tolerance allowed
calib.CalibFactorTolerancePercent = maxCalibFactorTolerancePercent;
if (calib.IsCalibFactorInTolerance(calibFactorRel.Value))
{
continue;
}
var warnMessage = $"Slot:{Slot}, Channel:{channel} - " +
$"Calibration factor is out of range({calibFactorRel.Value}rel)";
Logger.Warn(warnMessage);
// throw new ApplicationException(warnMessage);
}
var t = new JustageResults
{
pcbId = PcbId,
p1Target = reqDeviationPercent,
p1Value = _calibFactor[0].GetMeterRawCalibFactor(),
p2Target = reqDeviationPercent,
p2Value = _calibFactor[1].GetMeterRawCalibFactor(),
p3Target = reqDeviationPercent,
p3Value = _calibFactor[2].GetMeterRawCalibFactor(),
dt = DateTime.UtcNow,
testrunNr = testrunNr
};
try
{
var tmpUrl = "http://10.49.40.25/MeterProcessState/api/TestBench/SetCalibrationValues";
Logger.Info($"Request Url: {tmpUrl}");
//ToDO: Update to service URl
LocalWebRequest.PostAsJson<JustageResults>(t, tmpUrl);
}
catch (Exception ex)
{
Logger.Error($"Request Url: {ex.Message}");
}
}
/// <inheritdoc />
public void SetCalibFactorsAllChannels(Boolean justLog = false)
{
WriteRegister<Byte>(Register.Genesisflow.SampleRate, 2, checkRegister: true);
WriteRegister<UInt16>(Register.Genesisflow.TriggerIdle, 0x1234);
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
{
if (_calibFactor[channel].IsCalculated == false)
{
continue;
}
if (justLog)
{
Logger.Warn($"Slot:{Slot} - Calculated calibration factors but not stored to registers");
}
else
{
var registerRawCalibFactor = _calibFactor[channel].GetMeterRawCalibFactor();
var resultWrite = WriteRegister(_calibFactor[channel].RegisterToStoreCalibFactor,
registerRawCalibFactor, checkRegister: true);
Logger.Info($"Slot:{Slot}, Channel:{channel} - Stored calibration factor({_registersToStoreCalibFactor[channel]})");
//if (!string.IsNullOrEmpty(SerialNumber) && CurrentActionText.Contains("PG"))
//{
// var pathMain = NLogHelper.GetPath(_logger);
// var pathRaw = NLogHelper.GetPath(((LedSerialPort)StreamingPort).GetRawLogger());
// var basePath = Path.GetDirectoryName(pathMain);
// //
// var testRunString = CurrentActionText.Replace("PG", "");
//
if (resultWrite)
{
Logger.Warn($"Set calibration went wrong {_calibFactor[channel].RegisterToStoreCalibFactor}, with {registerRawCalibFactor}");
}
}
}
WriteRegister(Register.Genesisflow.ResetAccumulators, true);
//WriteRegister<UInt16>(Register.Genesisflow.ForwardArrow, 0, checkRegister: true);
WriteRegister<UInt16>(Register.Genesisflow.StoreCalibration, 1);
Logger.Info($"Slot:{Slot} - StoreCalibration {RegisterConverter.ByteArrayToValue<UInt16>(ReadRegister(Register.Genesisflow.StoreCalibration))}");
WriteRegister<UInt16>(Register.Genesisflow.TriggerActive, 1);
Logger.Info($"Slot:{Slot} - Set forward arrow of LCD, reset accumulators, set sample rate to 2Hz");
WriteRegister<Byte>(Register.Genesisflow.SampleRate, 10, checkRegister: true);
try
{
if (GetRegistersDic().Any(a => a.Key.RegisterName == "GENESISFLOW_DelayedLedOff"))
{
WriteRegister("GENESISFLOW_DelayedLedOff", 60 * 60 * 2, true);
Logger.Info($"Slot:{Slot} - GENESISFLOW_DelayedLedOff to {60 * 60 * 2}S");
}
else
{
Logger.Info($"Slot:{Slot} - GENESISFLOW_DelayedLedOff is not present");
}
}
catch (Exception ex)
{
Logger.Info($"Slot:{Slot} - {ex}");
}
}
}
}