Files
laatzen/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs
T
2024-09-17 09:33:06 +02:00

181 lines
7.3 KiB
C#

using System;
using Newtonsoft.Json;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.SoftwareAccessHelper;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
{
/// <summary>
/// Handler for the production status check. This will be feed by the DB.
/// - Calculation of drained battery,
/// - Assembly capability check,
/// - Shipping capability check.
/// </summary>
public static class GenesisStatusHandler
{
/// <summary>
/// Get all production infos for skip process checks or limits for production like:
/// - Battery drained percentage upper limit,
/// - Production due date for a special register,
/// - Required life time for assembly line,
/// - Required life time for shipping line.
/// </summary>
/// <param name="pcbId"></param>
/// <param name="orderNumber"></param>
/// <param name="productionStatus"></param>
/// <returns>true if successfully executed</returns>
/// <remarks date="2023-Mar-02" author="Roland Drabesch/Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <remarks date="2024-Jan-23" author="Roland Drabesch/Thomas Wiedebusch">
/// - Clone all properties coming from data base to reference (deep clone).
/// </remarks>
public static Boolean GetProductionSkipAndLifeTimeInfoFromDb(String pcbId, Int32 orderNumber,
GenesisStatus productionStatus)
{
if (string.IsNullOrEmpty(pcbId) || productionStatus == null)
{
return false;
}
GenesisStatus status;
try
{
var url = ""; // ServiceUrls.GetProductionSkipAndLifeTimeInfoServiceUrl();
url += $"{pcbId}&orderNumber={orderNumber}";
var response = LocalWebRequest.GetRequest(url, 2000);
status = JsonConvert.DeserializeObject<GenesisStatus>(response);
if (status == null)
{
return false;
}
}
catch (Exception )
{
return false;
}
var type = typeof(GenesisStatus);
foreach (var prop in type.GetProperties())
{
try
{
if( prop.CanWrite)
prop.SetValue(productionStatus, prop.GetValue(status, null), null);
}
catch (Exception)
{
// nothing to do, go ahead
}
}
return true;
}
/// <summary>
/// Read and calculate life time information.
/// </summary>
/// <param name="currentGenesis"></param>
/// <param name="status"></param>
/// <returns></returns>
/// <remarks date="2023-Mar-02" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean BuildLifeTimeInformation(GenesisMeter currentGenesis, GenesisStatus status)
{
Boolean retVal;
if (currentGenesis == null || status == null) return false;
// read information from genesis
try
{
if (!currentGenesis.IsLoggedOn) currentGenesis.Login();
status.ExceededLifeTime_s = RegisterConverter.ByteArrayToValue<UInt32>(
currentGenesis.ReadRegister(Register.Powermon.BatteryExceededSeconds));
status.DrainedBatteryLoad_uAs = RegisterConverter.ByteArrayToValue<UInt64>(
currentGenesis.ReadRegister(Register.Powermon.BatteryDrainedLoad, 8));
status.BatteryQuantity = RegisterConverter.ByteArrayToValue<Int32>(
currentGenesis.ReadRegister(Register.Powermon.BatteryQuantity));
status.InitialBatteryLoad_mAh = RegisterConverter.ByteArrayToValue<UInt32>(
currentGenesis.ReadRegister(Register.Powermon.BatteryInitialLoad));
currentGenesis.Logout();
retVal = CalculateLifeTime(status);
}
catch (Exception)
{
retVal = false;
}
return retVal;
}
/// <summary>
/// Calculation of life time values.
/// </summary>
/// <param name="status"></param>
/// <returns>true if all calculations could be executed</returns>
/// <remarks date="2023-Mar-02" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <remarks date="2023-Dec-??" author="Roland Drahbesch">
/// - Uniontown limits UNT.
/// </remarks>
public static Boolean CalculateLifeTime(GenesisStatus status)
{
var retVal = true;
// Calculate the initial overall battery load of all batteries in uAs as the drained load uses this unit.
var initialBatteryLoad_uAs = 1000 * 3600 * status.InitialBatteryLoad_mAh * (UInt64)status.BatteryQuantity;
// Relation of drained to initial load, set the battery to fully unloaded for failed check to force a recalculation
var drainedBatteryLoad_rel = 1.0;
if (initialBatteryLoad_uAs != 0)
{
drainedBatteryLoad_rel = (Double)status.DrainedBatteryLoad_uAs / initialBatteryLoad_uAs;
}
else
{
retVal = false;
}
status.DrainedBatteryLoadPercent = drainedBatteryLoad_rel * 100;
// The estimated life time uses the drained load over the actual exceeded life time and assumes, that further on
// an identical load will be consumed over the remaining life cycle. The initial load will be multiplied with the
// drained load relation. Set the estimated time to the exceeded time to force a recalculation on failed input.
var estimatedLifeTime_s = (Double)status.ExceededLifeTime_s;
if (drainedBatteryLoad_rel != 0.0)
{
estimatedLifeTime_s = status.ExceededLifeTime_s / drainedBatteryLoad_rel;
}
else
{
retVal = false;
}
var remainingLifetime_s = estimatedLifeTime_s - status.ExceededLifeTime_s;
// convert the seconds to years
status.RemainingLifeTimeYears = remainingLifetime_s / 3600 / 24 / 365.25;
status.UNTLimit = 1368000000 + (status.ExceededLifeTime_s * 77.7);
status.UNTStatus = status.UNTLimit >= status.DrainedBatteryLoad_uAs;
status.EMEALimit = 1368000000 + (status.ExceededLifeTime_s * 119.8);
status.EMEAStatus = status.UNTLimit >= status.DrainedBatteryLoad_uAs;
status.PreProductionUNTLimit = (1368000000/2) + (status.ExceededLifeTime_s * 77.7);
status.PreProductionUNTStatus = status.UNTLimit >= status.DrainedBatteryLoad_uAs;
status.PreProductionEMEALimit = (1368000000 / 2) + (status.ExceededLifeTime_s * 119.8);
status.PreProductionEMEAStatus = status.UNTLimit >= status.DrainedBatteryLoad_uAs;
return retVal;
}
}
}