merge
This commit is contained in:
@@ -327,6 +327,10 @@
|
||||
<Project>{F013A56B-7BE6-4852-9CD8-B971CD1ADD0C}</Project>
|
||||
<Name>GenesisConfig</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GenesisPwd\GenesisPwd.csproj">
|
||||
<Project>{AC434B18-4D7B-49BA-9AD5-0527C79E8297}</Project>
|
||||
<Name>GenesisPwd</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Protocols\ProtocolCore\ProtocolCore.csproj">
|
||||
<Project>{8BDD2789-96D4-43EA-AAD7-0F49D0347998}</Project>
|
||||
<Name>ProtocolCore</Name>
|
||||
|
||||
@@ -26,6 +26,7 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.ProtocolCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.Consts;
|
||||
@@ -959,13 +960,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2023-Jan-19" author="T.Wiedebusch">
|
||||
/// - Password had been reset to empty string if read from file, corrected!
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Feb-28" author="T.Wiedebusch">
|
||||
/// - Used <see cref="MeterPwdHandlerDb.GetPasswordFromDb"/>
|
||||
/// </remarks>
|
||||
private String GetPassword()
|
||||
{
|
||||
var url = ServiceUrls.GenesisGetPasswordServiceUrl();
|
||||
var password = "";
|
||||
|
||||
//without PCB ID it is not possible to login,
|
||||
//but if it is already assigned to this Gensis, don't read it again
|
||||
// without PCB ID it is not possible to login,
|
||||
// but if it is already assigned to this Genesis, don't read it again
|
||||
if (string.IsNullOrEmpty(PcbId))
|
||||
{
|
||||
//GetPcbId fills the PsbId property
|
||||
@@ -976,41 +977,29 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
url += PcbId;
|
||||
try
|
||||
// on unknown password try to get it from DB
|
||||
if (MeterPwdHandlerDb.GetPasswordFromDb(PcbId, out var password))
|
||||
{
|
||||
//use
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
password = responseJson.Trim('"');
|
||||
}
|
||||
_logger.Info($"Slot:{Slot} - Got password from GenesisPasswordServiceUrl, URL({url})");
|
||||
_logger.Info($"Slot:{Slot} - Got password from GenesisPasswordService, " +
|
||||
$"URL({ServiceUrls.GenesisGetPasswordServiceUrl() + PcbId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
_logger.Info($"Slot:{Slot} - Cannot get password from GenesisPasswordService, " +
|
||||
$"URL({url}), Error({ex.Message})");
|
||||
if (File.Exists(ProgramConfig.OfflineInfoFile))
|
||||
$"URL({ServiceUrls.GenesisGetPasswordServiceUrl() + PcbId}))");
|
||||
// try to read the password from an offline password file
|
||||
if (!File.Exists(ProgramConfig.OfflineInfoFile)) return password;
|
||||
|
||||
var listOfOfflinePasswords = JsonConvert.DeserializeObject<List<OfflinePasswordItem>>(
|
||||
File.ReadAllText(ProgramConfig.OfflineInfoFile));
|
||||
password = listOfOfflinePasswords.First(x => x.PcbId == PcbId).Password;
|
||||
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
var listOfOfflinePasswords = JsonConvert.DeserializeObject<List<OfflinePasswordItem>>(
|
||||
File.ReadAllText(ProgramConfig.OfflineInfoFile));
|
||||
password = listOfOfflinePasswords.First(x => x.PcbId == PcbId).Password;
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
_logger.Info($"Slot:{Slot} - Got password from password file!");
|
||||
}
|
||||
_logger.Info($"Slot:{Slot} - Got password for PcbId:{PcbId} from password file!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,42 +8,53 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd
|
||||
/// - passwords,
|
||||
/// - password-hashes (12 char from password - SHA1),
|
||||
/// - Order number,
|
||||
/// - Radio address and
|
||||
/// - Radio address,
|
||||
/// - Key set id,
|
||||
/// - Password file id and
|
||||
/// - Skeleton key.
|
||||
/// </summary>
|
||||
public class MeterPwdDb
|
||||
{
|
||||
//password file length is 160 bytes (8 passwords a 20 bytes SHA1)
|
||||
/// <summary>
|
||||
/// password file length is 160 bytes (8 passwords a 20 bytes SHA1)
|
||||
/// </summary>
|
||||
public const Int32 PwdFileLength = 160;
|
||||
|
||||
/// <summary>
|
||||
/// Skeleton key index in password list.
|
||||
/// </summary>
|
||||
public const Int32 SkeletonKeyIdx = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Password Level 8 index in 8 elements password list.
|
||||
/// </summary>
|
||||
public const Int32 PwdLevel8Idx = 7;
|
||||
|
||||
/// <summary>
|
||||
/// Order number for this Genesis.
|
||||
/// </summary>
|
||||
public Int64? OrderNumber = null;
|
||||
|
||||
/// <summary>
|
||||
/// Optional radio address.
|
||||
/// </summary>
|
||||
public Int64? RadioAddress = null;
|
||||
|
||||
/// <summary>
|
||||
/// Skeleton key for login if password file is not installed.
|
||||
/// </summary>
|
||||
public String Skeleton = "";
|
||||
|
||||
/// <summary>
|
||||
/// Password, which is the Skeleton, if password file not installed, or the PwdLevel8, if the password file is installed .
|
||||
/// </summary>
|
||||
public String Password = "";
|
||||
|
||||
/// <summary>
|
||||
/// List of hashes.
|
||||
/// </summary>
|
||||
public List<Byte[]> ListOfHashes = new List<Byte[]>();
|
||||
|
||||
/// <summary>
|
||||
/// List of passwords.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
@@ -26,29 +24,31 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd
|
||||
/// <remarks date="2023-Feb-23" author="Roland Drabesch/Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Feb-28" author="Roland Drabesch/Thomas Wiedebusch">
|
||||
/// - Used JsonConvert instead of StreamReader.
|
||||
/// </remarks>
|
||||
public static Boolean GetPasswordFromDb(String pcbId, out String password)
|
||||
{
|
||||
var url = ServiceUrls.GenesisGetPasswordServiceUrl();
|
||||
password = "";
|
||||
if (string.IsNullOrEmpty(pcbId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//todo: roland umstellen auf localwebrequest
|
||||
var http = (HttpWebRequest)WebRequest.Create(url + pcbId);
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
var url = ServiceUrls.GenesisGetPasswordServiceUrl();
|
||||
var response = LocalWebRequest.GetRequest(url + pcbId, 2000);
|
||||
password = JsonConvert.DeserializeObject<String>(response);
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
password = "";
|
||||
return false;
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
password = responseJson.Trim('"');
|
||||
}
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
password = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Status of Cordonel like:
|
||||
/// - Battery drainage,
|
||||
/// - Production date of electronics,
|
||||
/// - Due date for production,
|
||||
/// - Remaining life time,
|
||||
/// - Special permissions for production capability check for
|
||||
/// - Battery Drainage in %,
|
||||
/// - Remaining Life Time in years,
|
||||
/// - Production Due Date as DateTime.
|
||||
/// </summary>
|
||||
public class GenesisStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Data base primary key
|
||||
/// </summary>
|
||||
public Int32 Id;
|
||||
|
||||
/// <summary>
|
||||
/// Order number
|
||||
/// </summary>
|
||||
public Int32 OrderNumber;
|
||||
|
||||
/// <summary>
|
||||
/// PcbId.
|
||||
/// </summary>
|
||||
public String PcbId;
|
||||
|
||||
/// <summary>
|
||||
/// Skip radio parameter check
|
||||
/// </summary>
|
||||
public Boolean SkipRadioParametersCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Skip FW check. Normally the FW will be assigned to the latest released version
|
||||
/// and taken from the data base. Here special versions can be used for FW tests.
|
||||
/// </summary>
|
||||
public Boolean SkipFwCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Skip the look-up-table installation as this device may be used for development.
|
||||
/// </summary>
|
||||
public Boolean SkipLutCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Internally used to signal that production and shipping is proved and validated.
|
||||
/// </summary>
|
||||
public Boolean ProductionAccepted;
|
||||
|
||||
/// <summary>
|
||||
/// Date and time of production of electronics.
|
||||
/// </summary>
|
||||
public DateTime KitronProductionDate;
|
||||
|
||||
/// <summary>
|
||||
/// Last date until production has to be finished, can be extended by special permission
|
||||
/// </summary>
|
||||
public DateTime ProductionDueDate;
|
||||
|
||||
/// <summary>
|
||||
/// Remaining life time for Cordonel in years based on battery drainage.
|
||||
/// </summary>
|
||||
public Double RemainingLifeTimeYears;
|
||||
|
||||
/// <summary>
|
||||
/// Exceeded life time of all batteries in seconds.
|
||||
/// </summary>
|
||||
public UInt64 ExceededLifeTime_s;
|
||||
|
||||
/// <summary>
|
||||
/// Required life time in years for assembly, is dependent on region and special permission.
|
||||
/// </summary>
|
||||
public Double RequiredLifeTimeYearsAssembly;
|
||||
|
||||
/// <summary>
|
||||
/// Required life time in years for shipping, is dependent on region and special permission.
|
||||
/// </summary>
|
||||
public Double RequiredLifeTimeYearsShipping;
|
||||
|
||||
/// <summary>
|
||||
/// Battery drainage in percent.
|
||||
/// </summary>
|
||||
public Double DrainedBatteryLoadPercent;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum drained Battery load in percent.
|
||||
/// </summary>
|
||||
public Double MaxDrainedBatteryLoadPercent;
|
||||
|
||||
/// <summary>
|
||||
/// Number of batteries attached to Cordonel.
|
||||
/// </summary>
|
||||
public Int32 BatteryQuantity;
|
||||
|
||||
/// <summary>
|
||||
/// Initial capacity of one battery in mAh.
|
||||
/// </summary>
|
||||
public UInt64 InitialBatteryLoad_mAh;
|
||||
|
||||
/// <summary>
|
||||
/// Drained capacity of all batteries in uAs.
|
||||
/// </summary>
|
||||
public UInt64 DrainedBatteryPower_uAs;
|
||||
|
||||
/// <summary>
|
||||
/// Comment for approval and permissions reasons:
|
||||
/// e.g. "On customer requirement for test purposes the life time isn't of importance".
|
||||
/// </summary>
|
||||
public String ApprovalComment;
|
||||
|
||||
/// <summary>
|
||||
/// Name of approver for special permissions.
|
||||
/// </summary>
|
||||
public String ApproverName;
|
||||
|
||||
/// <summary>
|
||||
/// Date of approval.
|
||||
/// </summary>
|
||||
public DateTime ApprovalDate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{0F646872-D8DC-4EE5-989F-D4C73F0ACE3F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus</RootNamespace>
|
||||
<AssemblyName>Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\packages\Newtonsoft.Json.12.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GenesisStatusHandler.cs" />
|
||||
<Compile Include="GenesisStatus.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\CommonCore.Configuration\CommonCore.Configuration.csproj">
|
||||
<Project>{9EB1F659-6F73-4F65-BCAB-4114FD94F5FC}</Project>
|
||||
<Name>CommonCore.Configuration</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\SoftwareAccessHelper\SoftwareAccessHelper.csproj">
|
||||
<Project>{A33E3C6D-EAAE-4A20-A0EE-F9E6922FD029}</Project>
|
||||
<Name>SoftwareAccessHelper</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GenesisCore\GenesisCore.csproj">
|
||||
<Project>{04201E95-90A0-4B73-A72F-379739B2A3AE}</Project>
|
||||
<Name>GenesisCore</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Registers\Registers.csproj">
|
||||
<Project>{F4AAF7E6-7333-4284-B735-E32DEB076C64}</Project>
|
||||
<Name>Registers</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,136 @@
|
||||
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="status">production status</param>
|
||||
/// <returns>true if successfully executed</returns>
|
||||
/// <remarks date="2023-Mar-02" author="Roland Drabesch/Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
public static Boolean GetProductionSkipAndLifeTimeInfoFromDb(String pcbId, Int32 orderNumber,
|
||||
out GenesisStatus status)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pcbId))
|
||||
{
|
||||
status = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var url = ServiceUrls.GetProductionSkipAndLifeTimeInfoServiceUrl();
|
||||
url += $"{pcbId}&orderNumber={orderNumber}";
|
||||
var response = LocalWebRequest.GetRequest(url, 2000);
|
||||
status = JsonConvert.DeserializeObject<GenesisStatus>(response);
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
status = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and calculate life time information.
|
||||
/// </summary>
|
||||
/// <param name="currentGenesis"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <returns></returns>
|
||||
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.ConvertTo<UInt32>(
|
||||
currentGenesis.ReadRegister(Register.Powermon.BatteryExceededSeconds));
|
||||
status.DrainedBatteryPower_uAs = RegisterConverter.ConvertTo<UInt64>(
|
||||
currentGenesis.ReadRegister(Register.Powermon.BatteryDrainedLoad, 8));
|
||||
status.BatteryQuantity = RegisterConverter.ConvertTo<Int32>(
|
||||
currentGenesis.ReadRegister(Register.Powermon.BatteryQuantity));
|
||||
status.InitialBatteryLoad_mAh = RegisterConverter.ConvertTo<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>
|
||||
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.DrainedBatteryPower_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;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GenesisStatus")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("GenesisStatus")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("0f646872-d8dc-4ee5-989f-d4c73f0ace3f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -89,6 +89,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers
|
||||
{
|
||||
public static readonly String BatteryVoltage = "POWERMON_BatteryVoltage";
|
||||
public static readonly String BatteryQuantity = "POWERMON_BatteryQuantity";
|
||||
public static readonly String BatteryDrainedLoad = "POWERMON_TotalUsedCharge";
|
||||
public static readonly String BatteryInitialLoad = "POWERMON_BatteryMilliAHrRating";
|
||||
public static readonly String BatteryExceededSeconds = "POWERMON_TotalUsedSeconds";
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user