laatzen/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPowerCorrectionFile.cs
2025-03-18 15:02:08 +01:00

491 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Properties;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes;
using Xylem.Common.Utils.Crc16Ccitt;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
/// <summary>
/// Power correction file stored as reminder and log to meter
/// </summary>
public class MeterPowerCorrectionFile
{
/// <summary>
/// Drive and name for power correction file stored on meter
/// </summary>
public const String StrMeterPowCorrFileName = "1\\powcorr";
private readonly IGenesisMeter _currentGenesis;
private readonly MeterFile _meterFile;
// position of data in binary data of meter powcorr file
// file information
private const Int32 FileLengthIdx = 0;
private const Int32 FileLengthSize = sizeof(UInt16);
private const Int32 FileCrcIdx = FileLengthIdx + FileLengthSize;
private const Int32 FileCrcSize = sizeof(UInt16);
private const Int32 FileDataIdx = FileCrcIdx + FileCrcSize;
private const Int32 FileHeaderSize = FileLengthSize + FileCrcSize;
// common data size
private const Int32 ChargeSize = sizeof(UInt64);
private const Int32 TimeSize = sizeof(UInt32);
private const Int32 FwVersionSize = sizeof(UInt32);
private const Int32 RadioStateSize = sizeof(Byte);
private const Int32 PulseAdaptInstalledSize = sizeof(Boolean);
private const Int32 PulseModeSize = sizeof(Byte);
private const Int32 PulseSequenceCtrSize = sizeof(Byte);
private const Int32 PulseEvenDistributionSize = sizeof(Boolean);
// production data
private const Int32 ProdDateTimeIdx = FileDataIdx;
private const Int32 ProdTimeIdx = ProdDateTimeIdx + TimeSize;
private const Int32 ProdChargeIdx = ProdTimeIdx + TimeSize;
private const Int32 ProdRadioStateIdx = ProdChargeIdx + ChargeSize;
private const Int32 ProdPulseAdaptInstalledIdx = ProdRadioStateIdx + RadioStateSize;
private const Int32 ProdPulseModeIdx = ProdPulseAdaptInstalledIdx + PulseAdaptInstalledSize;
private const Int32 ProdPulseSequenceCtrIdx = ProdPulseModeIdx + PulseModeSize;
private const Int32 ProdPulseEvenDistributionIdx = ProdPulseSequenceCtrIdx + PulseSequenceCtrSize;
private const Int32 InitialBatteryLoadIdx = ProdPulseEvenDistributionIdx + PulseEvenDistributionSize;
private const Int32 InitialBatteryLoadSize = sizeof (UInt16);
private const Int32 BatteryQuantityIdx = InitialBatteryLoadIdx + InitialBatteryLoadSize;
private const Int32 BatteryQuantitySize = sizeof(Byte);
// field data
private const Int32 FieldFwVersionIdx = BatteryQuantityIdx + BatteryQuantitySize;
private const Int32 FieldDateTimeIdx = FieldFwVersionIdx + FwVersionSize;
private const Int32 FieldTimeIdx = FieldDateTimeIdx + TimeSize;
private const Int32 FieldChargeIdx = FieldTimeIdx + TimeSize;
private const Int32 FieldRadioStateIdx = FieldChargeIdx + ChargeSize;
private const Int32 FieldPulseAdaptInstalledIdx = FieldRadioStateIdx + RadioStateSize;
private const Int32 FieldPulseModeIdx = FieldPulseAdaptInstalledIdx + PulseAdaptInstalledSize;
private const Int32 FieldPulseSequenceCtrIdx = FieldPulseModeIdx + PulseModeSize;
private const Int32 FieldPulseEvenDistributionIdx = FieldPulseSequenceCtrIdx + PulseSequenceCtrSize;
// calculated
private const Int32 RequiredFwVersionIdx = FieldPulseEvenDistributionIdx + PulseEvenDistributionSize;
private const Int32 CalcPulseReportLengthIdx = RequiredFwVersionIdx + FwVersionSize;
private const Int32 CalcPulseReportLengthSize = sizeof(UInt32);
private const Int32 CalcPostProdTimeIdx = CalcPulseReportLengthIdx + CalcPulseReportLengthSize;
private const Int32 CalcOverestimatedChargeIdx = CalcPostProdTimeIdx + TimeSize;
private const Int32 CalcFixedEstimatedChargeIdx = CalcOverestimatedChargeIdx + ChargeSize;
private const Int32 CalcMinimumChargeIdx = CalcFixedEstimatedChargeIdx + ChargeSize;
private const Int32 CalcCorrectedChargeIdx = CalcMinimumChargeIdx + ChargeSize;
// estimate file size
private const Int32 FileSize = CalcCorrectedChargeIdx + ChargeSize;
// raw data
private Byte[] _meterBinData = new Byte[FileSize];
/// <summary>
/// Content of power correction meter file
/// </summary>
public readonly List<String> FileContent = new List<String>();
/// <summary>
/// Ctor
/// </summary>
/// <param name="currentGenesis"></param>
/// <remarks date="2024-May-08" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public MeterPowerCorrectionFile(IGenesisMeter currentGenesis)
{
_currentGenesis = currentGenesis;
_meterFile = new MeterFile(_currentGenesis);
}
/// <summary>
/// Read power correction meter file.
/// </summary>
/// <returns>true: file found</returns>
/// <remarks date="2024-May-08" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean ReadPowCorrMeterFile()
{
if (_currentGenesis == null || _meterFile == null)
return false;
try
{
var loginReminder = _currentGenesis.IsLoggedOn;
var retVal = _currentGenesis.ReLogin();
if (retVal)
{
FileContent.Clear();
retVal = _meterFile.ReadMeterFile(StrMeterPowCorrFileName, out var meterBinDataList);
_meterBinData = meterBinDataList.ToArray();
// Build a string list of recorded data
if (retVal)
{
retVal = BuildStringListOfPowCorrFileContent();
}
}
if (!loginReminder)
_currentGenesis.Logout();
return retVal;
}
catch (Exception e)
{
_currentGenesis.WriteLog(e.Message);
return false;
}
}
/// <summary>
/// Build a string list of logged power correction file content.
/// </summary>
/// <returns>true: file found</returns>
/// <remarks date="2024-May-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean BuildStringListOfPowCorrFileContent()
{
if (_meterBinData == null || _meterBinData.Length == 0 || _currentGenesis == null)
return false;
try
{
var fc = FileContent;
var bin = _meterBinData;
Byte[] value_u8a;
var ltlStatus = new GenesisStatus.GenesisStatus();
fc.Clear();
fc.Add(Resources.StrPowCorrFileInfo);
if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, ProdDateTimeIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrDateTime}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(TimeT))}");
if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, ProdTimeIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrTime_s}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}");
ltlStatus.ExceededLifeTime_s = RegisterConverter.ByteArrayToValue<UInt32>(value_u8a);
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, ProdChargeIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrCharge_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
ltlStatus.DrainedBatteryLoad_uAs = RegisterConverter.ByteArrayToValue<UInt64>(value_u8a);
if (CopyByteArray(value_u8a = new Byte[InitialBatteryLoadSize], bin, InitialBatteryLoadSize,
0, InitialBatteryLoadIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrInitialBatteryLoad_mAh}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt16))}");
ltlStatus.InitialBatteryLoad_mAh = RegisterConverter.ByteArrayToValue<UInt16>(value_u8a);
if (CopyByteArray(value_u8a = new Byte[BatteryQuantitySize], bin, BatteryQuantitySize,
0, BatteryQuantityIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrBatteryQuantity}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
ltlStatus.BatteryQuantity = RegisterConverter.ByteArrayToValue<Byte>(value_u8a);
if (GenesisStatusHandler.CalculateLifeTime(ltlStatus))
{
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrDrainedLoad_percent}" +
$": {ltlStatus.DrainedBatteryLoadPercent:F2}");
}
if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, FieldDateTimeIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrDateTime}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(TimeT))}");
if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, FieldTimeIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrTime_s}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}");
ltlStatus.ExceededLifeTime_s = RegisterConverter.ByteArrayToValue<UInt32>(value_u8a);
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, FieldChargeIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrCharge_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
ltlStatus.DrainedBatteryLoad_uAs = RegisterConverter.ByteArrayToValue<UInt64>(value_u8a);
if (GenesisStatusHandler.CalculateLifeTime(ltlStatus))
{
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrDrainedLoad_percent}" +
$": {ltlStatus.DrainedBatteryLoadPercent:F2}");
}
if (CopyByteArray(value_u8a = new Byte[RadioStateSize], bin, RadioStateSize, 0, ProdRadioStateIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrRadioSystemState}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[RadioStateSize], bin, RadioStateSize, 0, FieldRadioStateIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrRadioSystemState}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[PulseAdaptInstalledSize], bin, PulseAdaptInstalledSize, 0,
ProdPulseAdaptInstalledIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseAdapterInstallationState}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}");
if (CopyByteArray(value_u8a = new Byte[PulseAdaptInstalledSize], bin, PulseAdaptInstalledSize, 0,
FieldPulseAdaptInstalledIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseAdapterAutoDetected}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}");
if (CopyByteArray(value_u8a = new Byte[PulseModeSize], bin, PulseModeSize, 0, ProdPulseModeIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseMode}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[PulseModeSize], bin, PulseModeSize, 0, FieldPulseModeIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseMode}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[PulseSequenceCtrSize], bin, PulseSequenceCtrSize, 0,
ProdPulseSequenceCtrIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseSequenceCounter}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[PulseSequenceCtrSize], bin, PulseSequenceCtrSize, 0,
FieldPulseSequenceCtrIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseSequenceCounter}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}");
if (CopyByteArray(value_u8a = new Byte[PulseEvenDistributionSize], bin, PulseEvenDistributionSize, 0,
ProdPulseEvenDistributionIdx))
fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseEvenDistribution}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}");
if (CopyByteArray(value_u8a = new Byte[PulseEvenDistributionSize], bin, PulseEvenDistributionSize, 0,
FieldPulseEvenDistributionIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseEvenDistribution}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}");
if (CopyByteArray(value_u8a = new Byte[FwVersionSize], bin, FwVersionSize, 0, FieldFwVersionIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrOldFwVersion}" +
$": {GenesisMeter.BuildFlexnetFwVersion(out _, null, value_u8a[1], value_u8a[0])}");
if (CopyByteArray(value_u8a = new Byte[FwVersionSize], bin, FwVersionSize, 0, RequiredFwVersionIdx))
fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrNewFwVersion}" +
$": {GenesisMeter.BuildFlexnetFwVersion(out _, null, value_u8a[1], value_u8a[0])}");
if (CopyByteArray(value_u8a = new Byte[CalcPulseReportLengthSize], bin, CalcPulseReportLengthSize,
0, CalcPulseReportLengthIdx))
fc.Add($"{Resources.StrPowCorrPulseReportLength}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}");
if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, CalcPostProdTimeIdx))
fc.Add($"{Resources.StrPowCorrPostProdTime_s}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}");
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcOverestimatedChargeIdx))
fc.Add($"{Resources.StrPowCorrOverestimate_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcFixedEstimatedChargeIdx))
fc.Add($"{Resources.StrPowCorrFixedEstimateCharge_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcMinimumChargeIdx))
fc.Add($"{Resources.StrPowCorrOverestimateLimit_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcCorrectedChargeIdx))
fc.Add($"{Resources.StrPowCorrCorrectedCharge_uAs}" +
$": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}");
ltlStatus.DrainedBatteryLoad_uAs = RegisterConverter.ByteArrayToValue<UInt64>(value_u8a);
if (GenesisStatusHandler.CalculateLifeTime(ltlStatus))
{
fc.Add($"{Resources.StrPowCorrCalculation} - {Resources.StrPowCorrDrainedLoad_percent}" +
$": {ltlStatus.DrainedBatteryLoadPercent:F2}");
}
return true;
}
catch (Exception e)
{
_currentGenesis.WriteLog(e.Message);
return false;
}
}
/// <summary>
/// Copy byte arrays
/// </summary>
/// <param name="destination">destination array to copy to</param>
/// <param name="source">array to copy from</param>
/// <param name="size"></param>
/// <param name="destinationStartIndex"></param>
/// <param name="sourceStartIndex"></param>
/// <returns>true: success</returns>
/// <remarks date="2024-May-13" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean CopyByteArray(Byte[] destination, Byte[] source, Int32 size, Int32 destinationStartIndex = 0,
Int32 sourceStartIndex = 0)
{
if (_currentGenesis == null)
return false;
// avoid OOR copy
if (destination.Length < size + destinationStartIndex || source.Length < size + sourceStartIndex)
return false;
try
{
for (var c = 0; c < size; c++)
{
destination[destinationStartIndex + c] = source[sourceStartIndex + c];
}
return true;
}
catch (Exception e)
{
_currentGenesis.WriteLog(e.Message);
return false;
}
}
/// <summary>
/// Build the binary data as preparation before sending those to the meter file.
///
/// PRECONDITION: PowerCorrectionData has to be filled in advance!
/// </summary>
/// <returns>true: success</returns>
/// <remarks date="2024-May-13..15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <param name="powerCorrectionData">power correction</param>
/// <returns>if successfully copied</returns>
private Boolean BuildBinData(PowerCorrection powerCorrectionData)
{
if (powerCorrectionData == null || _currentGenesis == null)
return false;
try
{
if (_meterBinData == null)
_meterBinData = new Byte[FileSize];
var pc = powerCorrectionData;
// production
var timeT = new TimeT();
var dateTimeUtc = pc.ProductionDateTimeUtc ?? timeT.DateTimeUtc;
var secSince2000 = timeT.UtcAnyToSecondsSince2000(dateTimeUtc);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(secSince2000),
TimeSize, ProdDateTimeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionTotalUsedSeconds_s),
TimeSize, ProdTimeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionTotalUsedCharge_uAs),
ChargeSize, ProdChargeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionRadioSystemState),
RadioStateSize, ProdRadioStateIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionPulseAdapterIsInstalled),
PulseAdaptInstalledSize, ProdPulseAdaptInstalledIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionPulseMode),
PulseModeSize, ProdPulseModeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionPulseSequenceCounter),
PulseSequenceCtrSize, ProdPulseSequenceCtrIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionPulseEvenDistribution),
PulseEvenDistributionSize, ProdPulseEvenDistributionIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.InitialBatteryLoad_mAh),
InitialBatteryLoadSize, InitialBatteryLoadIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.BatteryQuantity),
BatteryQuantitySize, BatteryQuantityIdx);
// field
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualFwVersion),
FwVersionSize, FieldFwVersionIdx);
// reset timeT to 2000
timeT.SecondsSince2000 = 0;
dateTimeUtc = pc.ActualDateTimeUtc ?? timeT.DateTimeUtc;
secSince2000 = timeT.UtcAnyToSecondsSince2000(dateTimeUtc);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(secSince2000),
TimeSize, FieldDateTimeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualTotalUsedSeconds_s),
TimeSize, FieldTimeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualTotalUsedCharge_uAs),
ChargeSize, FieldChargeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualRadioSystemState),
RadioStateSize, FieldRadioStateIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseAdapterIsInstalled),
PulseAdaptInstalledSize, FieldPulseAdaptInstalledIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseMode),
PulseModeSize, FieldPulseModeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseSequenceCounter),
PulseSequenceCtrSize, FieldPulseSequenceCtrIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseEvenDistribution),
PulseEvenDistributionSize, FieldPulseEvenDistributionIdx);
// calculations
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.RequiredFwVersion),
FwVersionSize, RequiredFwVersionIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.PulseReportLength),
CalcPulseReportLengthSize, CalcPulseReportLengthIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.PostProductionTotalUsedSeconds_s),
TimeSize, CalcPostProdTimeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.OverestimatedTotalUsedCharge_uAs),
ChargeSize, CalcOverestimatedChargeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.FixedEstimateTotalUsedCharge_uAs),
ChargeSize, CalcFixedEstimatedChargeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.MinimumTotalUsedCharge_uAs),
ChargeSize, CalcMinimumChargeIdx);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.CorrectedTotalUsedCharge_uAs),
ChargeSize, CalcCorrectedChargeIdx);
// add file information
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(FileSize), FileLengthSize);
var crc = Crc16Ccitt.CalculateReversedLsb8408(_meterBinData);
CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(crc), FileCrcSize, FileCrcIdx);
return true;
}
catch (Exception e)
{
_currentGenesis.WriteLog(e.Message);
return false;
}
}
/// <summary>
/// Write the meter power correction file.
/// </summary>
/// <returns>true successfully written </returns>
/// <remarks date="2024-May-08..15" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <param name="powerCorrectionData"></param>
/// <returns>true if successfully written</returns>
public Boolean WritePowCorrMeterFile(PowerCorrection powerCorrectionData)
{
if (_currentGenesis == null || _meterFile == null || powerCorrectionData == null)
return false;
try
{
if (!BuildBinData(powerCorrectionData))
return false;
BuildStringListOfPowCorrFileContent();
var loginReminder = _currentGenesis.IsLoggedOn;
var retVal = _currentGenesis.ReLogin();
if (retVal)
{
_meterFile.UnlockEraseWriteMeterFile(StrMeterPowCorrFileName);
retVal = _meterFile.WriteMeterFile(StrMeterPowCorrFileName, _meterBinData.ToArray());
}
if (!loginReminder)
_currentGenesis.Logout();
return retVal;
}
catch (Exception e)
{
_currentGenesis.WriteLog(e.Message);
return false;
}
}
}
}