Prepared for LUT downloading, IrDASerialPort changed

This commit is contained in:
Thomas Wiedebusch 2022-03-02 14:24:47 +01:00
parent 835f242d95
commit 14eda41bdd
24 changed files with 2086 additions and 358 deletions

View File

@ -14,5 +14,5 @@ using System.Reflection;
//[assembly: AssemblyVersion("1.2.*.0")]
[assembly: AssemblyVersion("1.0.3.*")]
[assembly: AssemblyVersion("2.2.0.*")]
[assembly: AssemblyFileVersion("1.3.0.10")]

View File

@ -22,6 +22,9 @@
<Assembly Path="D:\Projekte\SENSUS_tfs_workspaces\WorkBenchV2\Main\Common\Ui\IrdaFunctionalTestApp\bin\Debug\Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.dll" />
&lt;/AssemblyExplorer&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/Hierarchy/EntityFrameworkOptions/IsAlreadyNotifiedAboutEntityFramework/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=a44a776d_002Dd671_002D4675_002Dac7b_002Db6775ec7f289/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Profiling/Configurations/=0/@EntryIndexedValue">&lt;data&gt;&lt;HostParameters type="LocalHostParameters" /&gt;&lt;Argument type="StandaloneArgument"&gt;&lt;Arguments IsNull="False"&gt;&lt;/Arguments&gt;&lt;FileName&gt;D:\Workspace\WorkBenchV2\Main\ZeroFlowTool\bin\Debug\GenesisDisplayTool.exe&lt;/FileName&gt;&lt;WorkingDirectory&gt;D:\Workspace\WorkBenchV2\Main\ZeroFlowTool\bin\Debug&lt;/WorkingDirectory&gt;&lt;Scope&gt;&lt;ProcessFilters /&gt;&lt;/Scope&gt;&lt;/Argument&gt;&lt;Info type="PerformanceInfo"&gt;&lt;MeasureType&gt;Sampling&lt;/MeasureType&gt;&lt;MeterKind&gt;Rdtsc&lt;/MeterKind&gt;&lt;InjectInfo&gt;&lt;SymbolSearch&gt;&lt;SearchPaths /&gt;&lt;/SymbolSearch&gt;&lt;Scope&gt;&lt;PatternFilters /&gt;&lt;DenyAttributeFilters /&gt;&lt;/Scope&gt;&lt;/InjectInfo&gt;&lt;/Info&gt;&lt;CoreOptions type="CoreOptions"&gt;&lt;CoreTempPath IsNull="False"&gt;&lt;/CoreTempPath&gt;&lt;RemoteEndPoint IsNull="False"&gt;&lt;/RemoteEndPoint&gt;&lt;AdditionalEnvironmentVariables /&gt;&lt;/CoreOptions&gt;&lt;HostOptions type="HostOptions"&gt;&lt;HostTempPath IsNull="False"&gt;&lt;/HostTempPath&gt;&lt;/HostOptions&gt;&lt;/data&gt;</s:String>
<s:String x:Key="/Default/Profiling/Configurations/=1/@EntryIndexedValue">&lt;data&gt;&lt;HostParameters type="LocalHostParameters" /&gt;&lt;Argument type="StandaloneArgument"&gt;&lt;Arguments IsNull="False"&gt;&lt;/Arguments&gt;&lt;FileName IsNull="False"&gt;&lt;/FileName&gt;&lt;WorkingDirectory IsNull="False"&gt;&lt;/WorkingDirectory&gt;&lt;Scope&gt;&lt;ProcessFilters /&gt;&lt;/Scope&gt;&lt;/Argument&gt;&lt;Info type="PerformanceInfo"&gt;&lt;MeasureType&gt;TracingInject&lt;/MeasureType&gt;&lt;MeterKind&gt;Rdtsc&lt;/MeterKind&gt;&lt;InjectInfo&gt;&lt;SymbolSearch&gt;&lt;SearchPaths /&gt;&lt;/SymbolSearch&gt;&lt;Scope&gt;&lt;PatternFilters&gt;&lt;Item /&gt;&lt;/PatternFilters&gt;&lt;DenyAttributeFilters /&gt;&lt;/Scope&gt;&lt;/InjectInfo&gt;&lt;/Info&gt;&lt;CoreOptions type="CoreOptions"&gt;&lt;CoreTempPath IsNull="False"&gt;&lt;/CoreTempPath&gt;&lt;RemoteEndPoint IsNull="False"&gt;&lt;/RemoteEndPoint&gt;&lt;AdditionalEnvironmentVariables /&gt;&lt;/CoreOptions&gt;&lt;HostOptions type="HostOptions"&gt;&lt;HostTempPath IsNull="False"&gt;&lt;/HostTempPath&gt;&lt;/HostOptions&gt;&lt;/data&gt;</s:String>
<s:String x:Key="/Default/Profiling/Configurations/=2/@EntryIndexedValue">&lt;data&gt;&lt;HostParameters type="LocalHostParameters" /&gt;&lt;Argument type="StandaloneArgument"&gt;&lt;Arguments IsNull="False"&gt;&lt;/Arguments&gt;&lt;FileName IsNull="False"&gt;&lt;/FileName&gt;&lt;WorkingDirectory IsNull="False"&gt;&lt;/WorkingDirectory&gt;&lt;Scope&gt;&lt;ProcessFilters /&gt;&lt;/Scope&gt;&lt;/Argument&gt;&lt;Info type="TimelineInfo" /&gt;&lt;CoreOptions type="CoreOptions"&gt;&lt;CoreTempPath IsNull="False"&gt;&lt;/CoreTempPath&gt;&lt;RemoteEndPoint IsNull="False"&gt;&lt;/RemoteEndPoint&gt;&lt;AdditionalEnvironmentVariables /&gt;&lt;/CoreOptions&gt;&lt;HostOptions type="HostOptions"&gt;&lt;HostTempPath IsNull="False"&gt;&lt;/HostTempPath&gt;&lt;ReprofileDisableReason&gt;LaunchedByReSharperUnitTestRunner&lt;/ReprofileDisableReason&gt;&lt;/HostOptions&gt;&lt;/data&gt;</s:String>

View File

@ -630,6 +630,11 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
/// <remarks date="2018-Oct-23" author="T.Wiedebusch">
/// - Doubling of sync byte in protocol behind sync byte itself implemented
/// </remarks>
/// <remarks date="2022-Feb-25" author="T.Wiedebusch">
/// - RTS signal trial as MOXA sometimes takes two messages and combines these two one!
/// As the Genesis needs a separated wake-up message with a following delay before the
/// real payload message, this causes a lot of trouble.
/// </remarks>
protected void PhysicalWrite(Byte[] txBuffer)
{
try
@ -649,7 +654,11 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
}
}
}
_serialPort.RtsEnable = true;
_serialPort.Write(txByteList.ToArray(), 0, txByteList.Count);
_serialPort.RtsEnable = false;
OnRawRecordSendOut?.Invoke(this, new ListBytePortDataEventArgs(txByteList, DateTimeOffset.UtcNow));
}

View File

@ -22,15 +22,22 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
/// - wakeup burst pattern changed from 2 times 0xF0 to 4 times 0x01,
/// - required delay from 500µs to 1ms between wakeup burst and data.
/// </remarks>
/// <remarks date="2022-Mar-03" author="T.Wiedebusch">
/// - Generated the required delay with an 8 Byte pattern, as MOXA interface collects data
/// and sends it in one burst, meaning it sends the wake up and payload without delay.
/// So including a pattern instead will force this delay. At 115.200 kBit/s a Byte of 8 Bit
/// one start and one stop step resulting in 10 bits with a Byte length of 86.8 µs. An 8
/// Byte pattern will generate a 694 µs delay.
/// </remarks>
protected override void SpecificPortWrite(Byte[] tx)
{
//send wake up burst with two 0xF0 byte
//var wakeUpBurst = new Byte[] { 0xF0, 0xF0 };
//send wake up burst
var wakeUpBurst = new Byte[] { 0x01, 0x01, 0x01, 0x01 };
PhysicalWrite(wakeUpBurst);
//delay at least 1ms
Thread.Sleep(1);
//delay at least 500 µs
var delayPattern = new Byte[] { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F };
PhysicalWrite(delayPattern);
//send the IrDA record
PhysicalWrite(tx);

View File

@ -0,0 +1,53 @@
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts
{
/// <summary>
/// Genesis meter lookup table update states
/// </summary>
public enum LutUpdateState
{
/// <summary>
/// Metrology lookup table update state Idle
/// </summary>
Idle,
/// <summary>
/// Single step failed
/// </summary>
StepFailed,
/// <summary>
/// Entire process failed
/// </summary>
UpdateFailed,
/// <summary>
/// Start initial FW update
/// </summary>
StartInitial,
/// <summary>
/// Repeat update
/// </summary>
RepeatLutUpdate,
/// <summary>
/// Upload lookup table file
/// </summary>
UploadLutFile,
/// <summary>
/// Download lookup table file
/// </summary>
DownloadLutFile,
/// <summary>
/// Compare lookup table file
/// </summary>
CompareLutFile,
/// <summary>
/// Download the CRC, the meter size and store calibration as preparation for the lookup table
/// </summary>
PrepareLutDownload,
/// <summary>
/// Erase lookup table file
/// </summary>
EraseLutFile,
/// <summary>
/// Delimiter for list
/// </summary>
LutUpdateStateListDelimiter
}
}

View File

@ -66,11 +66,13 @@
<Compile Include="..\..\..\..\.shared\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Consts\LutUpdateState.cs" />
<Compile Include="Consts\FwUpdateState.cs" />
<Compile Include="Consts\FwUpdateStateInfo.cs" />
<Compile Include="Consts\FwUpdateStateText.cs" />
<Compile Include="MeterFileRestore.cs" />
<Compile Include="MeterFilesEraseRestore.cs" />
<Compile Include="MeterLutUpdate.cs" />
<Compile Include="MeterFwUpdate.cs" />
<Compile Include="MeterFwUpdateCapability.cs" />
<Compile Include="MeterFwUpdateRuler.cs" />

View File

@ -0,0 +1,553 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Properties;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Utils.ProcessExec;
using Xylem.Common.Utils.ProcessExec.EventArguments;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
/// <summary>
/// Meter lookup table for metrology update procedure
/// </summary>
public class MeterLutUpdate : IProcessState
{
#region Variables
/// <summary>
/// Port scan result event for message dispatcher to caller
/// </summary>
public event EventHandler<ProcessExecEventArgs> OnProcessUpdate;
//disk and name of lookup file
private const String StrLutFileName = "1\\mettbl";
//disk and name of lookup file
private const String StrLutBackupFileName = "1\\mettbl_b";
// string as identifier for Genesis lookup table
private const String TablesFileMagic = "GEN_LUT";
private const String StrProcessLut = "Processing metrology lookup table";
//trigger update retries
private const Int32 RegisterWriteRetries = 2;
//update reties for files
private const Int32 FileWriteRetries = 0;
//retry of entire update procedure
private const Int32 UpdateProcedureRetries = 5;
//threshold to increase the file write timing
private const Int32 IncreaseTimeoutUpdateProcedureRetries = 4;
private Int32 _updateProcedureRetryCtr;
private GenesisMeter _genesisMeter;
private MeterFile _meterFile;
// Text for caller to inform about actual process being carried out
private String _actualOperation;
private LutUpdateState _lutUpdateState;
// Process counter for caller to monitor actual progress
private Int32 _processedBytesCtr;
private Int32 _overallBytesCtr;
// Look up table file
private Int32 _lutCrc;
private Byte _meterSize;
public FileApplications LutFile;
#endregion
#region Events
/// <summary>
/// Process update event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2020-Dec-10" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public virtual void ProcessUpdate_Event(Object sender, ProcessExecEventArgs e)
{
// copy text from overall messages to actual, because this is from sub-routine
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(StrProcessLut,
OverallProcessCtrPercent, _actualOperation, e.OverallProcessPercent));
}
#endregion
#region Information
/// <summary>
/// Process counter in percent
/// </summary>
/// <remarks date="2019-Jun-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Double OverallProcessCtrPercent
{
get
{
var processFileBytes = _meterFile?.ProcessedBytesCtr ?? 0;
return 100.0 * (processFileBytes + _processedBytesCtr) /
(_overallBytesCtr > 0 ? _overallBytesCtr : 1);
}
}
/// <summary>
/// Single file process counter in percent
/// </summary>
/// <remarks date="2019-Jun-24" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Double SingleFileProcessCtrPercent => _meterFile?.ProcessCtrPercent ?? 0;
#endregion
#region CtorAssignment
/// <summary>
/// Ctor
/// </summary>
/// <param name="genesisMeter"></param>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public MeterLutUpdate(GenesisMeter genesisMeter)
{
if (genesisMeter == null) return;
AssignGenesis(genesisMeter);
}
/// <summary>
/// Assign new genesis
/// </summary>
/// <param name="genesisMeter"></param>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public void AssignGenesis(GenesisMeter genesisMeter)
{
_genesisMeter = genesisMeter;
_actualOperation = "";
LutFile = null;
_lutUpdateState = LutUpdateState.Idle;
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
if (_meterFile == null) return;
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
}
#endregion
#region ProcessInformation
/// <summary>
/// Returns the actual file in process for update
/// </summary>
/// <returns></returns>
/// <remarks date="2019-Jun-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetActualOperation()
{
return _actualOperation;
}
/// <summary>
/// Returns the LUT Update state
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-25" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetLutUpdateStateOperation()
{
return _lutUpdateState == LutUpdateState.Idle ? "" : "Downloading...";
}
#endregion
#region Actions
/// <summary>
/// Try to re-establish the file system, therefor logout to close all open files
/// and login again.
/// </summary>
/// <remarks date="2019-Jun-21" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2019-Jun-28" author="Thomas Wiedebusch">
/// - Enable auto-logon added
/// </remarks>
/// <remarks date="2019-Jul-03" author="Thomas Wiedebusch">
/// - Removed auto-logon
/// </remarks>
public void ReestablishMeterFileSystem()
{
_genesisMeter?.Logout();
_genesisMeter?.ReLogin();
}
private Boolean _stopUpdateProcess;
/// <summary>
/// Stop the update process
/// </summary>
public Boolean StopUpdateProcess
{
get => _stopUpdateProcess;
set
{
_stopUpdateProcess = value;
if (_meterFile != null)
{
_meterFile.StopProcess = value;
}
_lutUpdateState = LutUpdateState.UpdateFailed;
}
}
/// <summary>
/// Update meter lookup table
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean UpdateMeterLut()
{
if (!UpdatePreparation())
{
return false;
}
_lutUpdateState = LutUpdateState.StartInitial;
while (_lutUpdateState != LutUpdateState.Idle && !StopUpdateProcess)
{
LutUpdateStateMachine();
}
return ExitPreparation(true);
}
/// <summary>
/// Upload lookup table file and compare with the loaded from file system
/// </summary>
/// <remarks date="2019-Jun-29" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean VerifyLutFile()
{
if (!UpdatePreparation())
{
return false;
}
return ExitPreparation(true);
}
/// <summary>
/// Reset lookup table update process and all lists and counters
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public void ResetAll()
{
LutFile = null;
//remove the update stop action
StopUpdateProcess = false;
//reset all counters
_processedBytesCtr = 0;
_overallBytesCtr = 0;
_updateProcedureRetryCtr = 0;
//set state machine for automatic FW update
_lutUpdateState = LutUpdateState.Idle;
_actualOperation = "";
//logout/login/auto-login
ReestablishMeterFileSystem();
_genesisMeter?.Logout();
}
/// <summary>
/// Common update preparation and check
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean UpdatePreparation()
{
_actualOperation = "";
_lutUpdateState = LutUpdateState.Idle;
_meterFile = new MeterFile(_genesisMeter);
if (_meterFile != null) _meterFile.OnProcessUpdate += ProcessUpdate_Event;
_genesisMeter?.ReLogin();
_genesisMeter?.SetProcessState(DisplayCodes.FwUpdateActive, false);
if (_genesisMeter == null || !_genesisMeter.IsLoggedOn)
{
return false;
}
//set default timeout for file write operation
_meterFile.SetDefaultFileWriteTimeout();
//remove the update stop action
StopUpdateProcess = false;
return true;
}
/// <summary>
/// Common exit routine
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean ExitPreparation(Boolean returnValue)
{
if (_meterFile != null) _meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
ReestablishMeterFileSystem();
_genesisMeter?.Logout();
if (!StopUpdateProcess)
{
return returnValue;
}
_actualOperation = Resources.StrWaiting;
return false;
}
#endregion
#region StateMachine
/// <summary>
/// State machine for metrology lookup table update process
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private void LutUpdateStateMachine()
{
switch (_lutUpdateState)
{
case LutUpdateState.Idle:
break;
case LutUpdateState.StartInitial:
_updateProcedureRetryCtr = 0;
_lutUpdateState = LutUpdateState.PrepareLutDownload;
break;
case LutUpdateState.PrepareLutDownload:
_lutUpdateState = PrepareLutDownload() ? LutUpdateState.DownloadLutFile : LutUpdateState.StepFailed;
break;
case LutUpdateState.DownloadLutFile:
_lutUpdateState = DownloadLutFile() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
break;
case LutUpdateState.StepFailed:
_processedBytesCtr = 0;
_overallBytesCtr = 0;
_lutUpdateState = _updateProcedureRetryCtr++ < UpdateProcedureRetries
? LutUpdateState.RepeatLutUpdate
: LutUpdateState.UpdateFailed;
break;
case LutUpdateState.RepeatLutUpdate:
_processedBytesCtr = 0;
_overallBytesCtr = 0;
_lutUpdateState = LutUpdateState.DownloadLutFile;
if (_updateProcedureRetryCtr >= IncreaseTimeoutUpdateProcedureRetries)
{
_meterFile?.SetExtremeFileWriteTimeout();
}
break;
case LutUpdateState.UpdateFailed:
_processedBytesCtr = 0;
_overallBytesCtr = 0;
StopUpdateProcess = true;
_lutUpdateState = LutUpdateState.Idle;
break;
case LutUpdateState.UploadLutFile:
break;
case LutUpdateState.CompareLutFile:
break;
case LutUpdateState.EraseLutFile:
break;
default:
_lutUpdateState = LutUpdateState.Idle;
break;
}
}
#endregion
#region LutFile
/// <summary>
/// Check the content of the metrology lookup table file:
/// - begins with "APP>",
/// - Application ID at position 0x28,
/// - CRC at position 0x04 LSB, 0x05 MSB
/// - Version at position 0x06 and 0x07 decimal
/// - Build upgrade meter file name
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-25" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private static Boolean ValidateLutFile()
{
//var fileApp = new FileApplications();
//fileApp.AppId = fileApp.BinData[FileAppAppIdIndex];
//fileApp.Crc = (UInt16)(fileApp.BinData[FileAppCrcIndex] + (fileApp.BinData[FileAppCrcIndex + 1] << 8));
//fileApp.Version = (UInt32)((fileApp.BinData[FileAppVersionIndex] & 0x0F)
// + ((fileApp.BinData[FileAppVersionIndex] & 0xF0) >> 4) * 10
// + (fileApp.BinData[FileAppVersionIndex + 1] & 0x0F) * 100
// + ((fileApp.BinData[FileAppVersionIndex + 1] & 0xF0) >> 4) * 1000);
//fileApp.StrVersion = GenesisMeter.BuildFwVersionString(fileApp.BinData[FileAppVersionIndex + 1],
// fileApp.BinData[FileAppVersionIndex]);
//var fileAppStartId = Encoding.UTF8.GetString(fileApp.BinData.ToArray(), 0, 4);
////check update file start identifier
//if (fileAppStartId != StrFileAppStartId)
//{
// return false;
//}
////TODO THW check CRC
////TODO THW check upgrade file name against content to select a valid package
////the meter file name is needed for writing the file to the meter or reading it back
//fileApp.MeterFilename = StrUpgradeAppPartialFileName + $"{fileApp.AppId:X2}";
return true;
}
/// <summary>
/// Download the CRC, the meter size and store calibration as preparation for the lookup table
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean PrepareLutDownload()
{
Boolean returnValue;
var retryCtr = 0;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(5000);
do
{
returnValue = _genesisMeter.WriteRegister<Byte>(Register.Genesisflow.MeterSize, _meterSize);
returnValue &= _genesisMeter.WriteRegister<Int32>(Register.Genesisflow.LookupFileCrc, _lutCrc);
returnValue &= _genesisMeter.WriteRegister<Byte>(Register.Genesisflow.StoreCalibration, 1);
if (!returnValue)
{
ReestablishMeterFileSystem();
}
} while (!returnValue && retryCtr++ < RegisterWriteRetries && !StopUpdateProcess);
//set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return returnValue && !StopUpdateProcess;
}
/// <summary>
/// Download the metrology lookup table files
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean DownloadLutFile()
{
//counters for actual process information
_processedBytesCtr = 0;
_overallBytesCtr = 0;
var retryCtr = 0;
Boolean returnValue;
//write file portion and retry if not successful
do
{
returnValue = _meterFile.WriteMeterFile(StrLutFileName, LutFile.BinData.ToArray());
returnValue &= _meterFile.WriteMeterFile(StrLutBackupFileName, LutFile.BinData.ToArray());
if (!returnValue)
{
ReestablishMeterFileSystem();
}
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
returnValue &= retryCtr <= FileWriteRetries;
//update information for process bar
_processedBytesCtr += LutFile.BinData.Count;
return !StopUpdateProcess && returnValue;
}
/// <summary>
/// Load file from memory
/// </summary>
/// <param name="filePathName">to binary files</param>
/// <returns></returns>
/// <remarks date="2022-Feb-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean LoadLutFile(String filePathName)
{
if (!File.Exists(filePathName))
{
return false;
}
LutFile = null;
LutFile = new FileApplications(filePathName)
{
BinData = new List<Byte>(File.ReadAllBytes(filePathName))
};
// validate the file
return ValidateLutFile();
}
#endregion
}
}

View File

@ -81,6 +81,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers
public static readonly String StartHit = "GENESISFLOW_StartHit";
public static readonly String NumFirePulses = "GENESISFLOW_NumFirePulses";
public static readonly String LookupFileCrc = "GENESISFLOW_LookupFileCrc";
};

View File

@ -1 +1 @@
0d85a5b3a7561b41163c20e5dc7713bcd0d65555
f64d563def603c89cafafa61a3219ba97e1e344c

View File

@ -259,7 +259,7 @@
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(116, 25);
this.button1.TabIndex = 0;
this.button1.Text = "Set Trigger Active";
this.button1.Text = "Clear Display";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//

View File

@ -18,7 +18,6 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Logic.ProductionOrderCore.FW;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.Ui.GenesisToolBox.Properties;
@ -120,13 +119,12 @@ namespace Xylem.Common.Ui.GenesisToolBox
"This is a stepwise update, proceed until update is completed!\n";
private const String StrUpdateErrorMessage =
"FW UPDATE FAILED!\n\n";
private FwSource fwSource = FwSource.File;
private FwSource _fwSource = FwSource.File;
private enum FwSource
{
File,
Production,
Db,
// Production,
Db
}
#endregion
#region FormControls
@ -1026,7 +1024,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
_packageFileToFileAppsValidated = _meterFwUpdate.ValidateFileAppsWithPackageFile();
}
catch (Exception e)
catch (Exception)
{
if (_meterFwUpdate.CoreRevisionMaximum == null)
MessageBoxShow(@"Core Revision missing in ADF!", @"FAILED",
@ -1170,9 +1168,10 @@ namespace Xylem.Common.Ui.GenesisToolBox
private void btnOpenPackageControlFile_Click(Object sender, EventArgs e)
{
////reload last path
//reload last path
dlgOpenPackageFile.InitialDirectory = DefaultPackageFile;
dlgOpenPackageFile.DefaultExt = ".txt";
if (dlgOpenPackageFile.ShowDialog() != DialogResult.OK)
{
return;
@ -1653,11 +1652,11 @@ namespace Xylem.Common.Ui.GenesisToolBox
private void checkSelectionChanged(FwSource newMode)
{
if (newMode == fwSource)
if (newMode == _fwSource)
{
return;
}
fwSource = newMode;
_fwSource = newMode;
}
private void PushFwFile(MeterFwUpdate meterFwUpdate)
@ -1774,14 +1773,14 @@ namespace Xylem.Common.Ui.GenesisToolBox
private void button1_Click(Object sender, EventArgs e)
{
if (_currentGenesis == null || !_currentGenesis.IsLoggedOn)
if (_currentGenesis == null ) return;
if (!_currentGenesis.IsLoggedOn)
{
return;
}
else
{
_currentGenesis.SetLcdText(true, new Byte[] { 0x00, 0x00, 0x00, 0x00 });
_currentGenesis.Login();
}
_currentGenesis.SetLcdText(true, new Byte[] { 0x00, 0x00, 0x00, 0x00 });
_currentGenesis.Logout();
}
private void btnFixBat_Click(Object sender, EventArgs e)

View File

@ -0,0 +1,368 @@
namespace Xylem.Common.Ui.GenesisToolBox
{
partial class FrmLutUpdate
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.grpSetup = new System.Windows.Forms.GroupBox();
this.lblCoreRevision = new System.Windows.Forms.Label();
this.btnConnect = new System.Windows.Forms.Button();
this.lblConnectPcb = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.cbComSlot = new System.Windows.Forms.ComboBox();
this.lblWaitingForMeterResponse = new System.Windows.Forms.Label();
this.btnStopFwUpdate = new System.Windows.Forms.Button();
this.btnDownloadLutFile = new System.Windows.Forms.Button();
this.lblOverall = new System.Windows.Forms.Label();
this.barSingleProgressUpdate = new System.Windows.Forms.ProgressBar();
this.lblActualProcess = new System.Windows.Forms.Label();
this.barOverallProgressUpdate = new System.Windows.Forms.ProgressBar();
this.tmrProgressUpdate = new System.Windows.Forms.Timer(this.components);
this.dlgOpenLuFile = new System.Windows.Forms.OpenFileDialog();
this.lblFwUpdateInfo = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.tbxLutFilePathName = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.btnOpenLutFile = new System.Windows.Forms.Button();
this.label9 = new System.Windows.Forms.Label();
this.lblUpdateTime = new System.Windows.Forms.Label();
this.lblLutFileLoadedInfo = new System.Windows.Forms.Label();
this.grpSetup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// grpSetup
//
this.grpSetup.Controls.Add(this.lblCoreRevision);
this.grpSetup.Controls.Add(this.btnConnect);
this.grpSetup.Controls.Add(this.lblConnectPcb);
this.grpSetup.Controls.Add(this.label2);
this.grpSetup.Controls.Add(this.cbComSlot);
this.grpSetup.Location = new System.Drawing.Point(12, 56);
this.grpSetup.Name = "grpSetup";
this.grpSetup.Size = new System.Drawing.Size(248, 153);
this.grpSetup.TabIndex = 24;
this.grpSetup.TabStop = false;
this.grpSetup.Text = "Connection";
//
// lblCoreRevision
//
this.lblCoreRevision.AutoSize = true;
this.lblCoreRevision.Location = new System.Drawing.Point(7, 53);
this.lblCoreRevision.Name = "lblCoreRevision";
this.lblCoreRevision.Size = new System.Drawing.Size(55, 13);
this.lblCoreRevision.TabIndex = 25;
this.lblCoreRevision.Text = "----------------";
//
// btnConnect
//
this.btnConnect.Location = new System.Drawing.Point(10, 118);
this.btnConnect.Name = "btnConnect";
this.btnConnect.Size = new System.Drawing.Size(116, 24);
this.btnConnect.TabIndex = 24;
this.btnConnect.Text = "Connect";
this.btnConnect.UseVisualStyleBackColor = true;
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
//
// lblConnectPcb
//
this.lblConnectPcb.AutoSize = true;
this.lblConnectPcb.Location = new System.Drawing.Point(7, 26);
this.lblConnectPcb.Name = "lblConnectPcb";
this.lblConnectPcb.Size = new System.Drawing.Size(100, 13);
this.lblConnectPcb.TabIndex = 23;
this.lblConnectPcb.Text = "NOT CONNECTED";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 85);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(28, 13);
this.label2.TabIndex = 20;
this.label2.Text = "Slot:";
//
// cbComSlot
//
this.cbComSlot.FormattingEnabled = true;
this.cbComSlot.Items.AddRange(new object[] {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20"});
this.cbComSlot.Location = new System.Drawing.Point(37, 81);
this.cbComSlot.Name = "cbComSlot";
this.cbComSlot.Size = new System.Drawing.Size(37, 21);
this.cbComSlot.TabIndex = 5;
this.cbComSlot.Text = "1";
this.cbComSlot.SelectedIndexChanged += new System.EventHandler(this.cbComSlot_SelectedIndexChanged);
//
// lblWaitingForMeterResponse
//
this.lblWaitingForMeterResponse.AutoSize = true;
this.lblWaitingForMeterResponse.ForeColor = System.Drawing.Color.Red;
this.lblWaitingForMeterResponse.Location = new System.Drawing.Point(532, 223);
this.lblWaitingForMeterResponse.Name = "lblWaitingForMeterResponse";
this.lblWaitingForMeterResponse.Size = new System.Drawing.Size(182, 13);
this.lblWaitingForMeterResponse.TabIndex = 18;
this.lblWaitingForMeterResponse.Text = "WAITING FOR METER RESPONSE";
//
// btnStopFwUpdate
//
this.btnStopFwUpdate.Location = new System.Drawing.Point(310, 118);
this.btnStopFwUpdate.Name = "btnStopFwUpdate";
this.btnStopFwUpdate.Size = new System.Drawing.Size(116, 25);
this.btnStopFwUpdate.TabIndex = 8;
this.btnStopFwUpdate.Text = "STOP";
this.btnStopFwUpdate.UseVisualStyleBackColor = true;
this.btnStopFwUpdate.Click += new System.EventHandler(this.btnStopFwUpdate_Click);
//
// btnDownloadLutFile
//
this.btnDownloadLutFile.Location = new System.Drawing.Point(310, 86);
this.btnDownloadLutFile.Name = "btnDownloadLutFile";
this.btnDownloadLutFile.Size = new System.Drawing.Size(116, 25);
this.btnDownloadLutFile.TabIndex = 0;
this.btnDownloadLutFile.Text = "Download";
this.btnDownloadLutFile.UseVisualStyleBackColor = true;
this.btnDownloadLutFile.Click += new System.EventHandler(this.btnDownloadLutFile_Click);
//
// lblOverall
//
this.lblOverall.AutoSize = true;
this.lblOverall.Location = new System.Drawing.Point(21, 260);
this.lblOverall.Name = "lblOverall";
this.lblOverall.Size = new System.Drawing.Size(80, 13);
this.lblOverall.TabIndex = 7;
this.lblOverall.Text = "Overall process";
//
// barSingleProgressUpdate
//
this.barSingleProgressUpdate.Location = new System.Drawing.Point(12, 239);
this.barSingleProgressUpdate.Name = "barSingleProgressUpdate";
this.barSingleProgressUpdate.Size = new System.Drawing.Size(702, 18);
this.barSingleProgressUpdate.TabIndex = 6;
this.barSingleProgressUpdate.Visible = false;
//
// lblActualProcess
//
this.lblActualProcess.AutoSize = true;
this.lblActualProcess.Location = new System.Drawing.Point(21, 223);
this.lblActualProcess.Name = "lblActualProcess";
this.lblActualProcess.Size = new System.Drawing.Size(76, 13);
this.lblActualProcess.TabIndex = 4;
this.lblActualProcess.Text = "Process status";
//
// barOverallProgressUpdate
//
this.barOverallProgressUpdate.Location = new System.Drawing.Point(12, 276);
this.barOverallProgressUpdate.Name = "barOverallProgressUpdate";
this.barOverallProgressUpdate.Size = new System.Drawing.Size(702, 18);
this.barOverallProgressUpdate.TabIndex = 3;
this.barOverallProgressUpdate.Visible = false;
//
// tmrProgressUpdate
//
this.tmrProgressUpdate.Interval = 200;
this.tmrProgressUpdate.Tick += new System.EventHandler(this.tmrProgressUpdate_Tick);
//
// dlgOpenLuFile
//
this.dlgOpenLuFile.Filter = "metrology lookup tables (*.lut)|*.lut";
//
// lblFwUpdateInfo
//
this.lblFwUpdateInfo.AutoSize = true;
this.lblFwUpdateInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblFwUpdateInfo.Location = new System.Drawing.Point(12, 34);
this.lblFwUpdateInfo.Name = "lblFwUpdateInfo";
this.lblFwUpdateInfo.Size = new System.Drawing.Size(72, 13);
this.lblFwUpdateInfo.TabIndex = 27;
this.lblFwUpdateInfo.Text = "Version: 0.0.0";
//
// pictureBox1
//
this.pictureBox1.Image = global::Xylem.Common.Ui.GenesisToolBox.Properties.Resources.SensusLogoXylem;
this.pictureBox1.Location = new System.Drawing.Point(611, 3);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(102, 54);
this.pictureBox1.TabIndex = 29;
this.pictureBox1.TabStop = false;
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.lblLutFileLoadedInfo);
this.groupBox1.Controls.Add(this.btnDownloadLutFile);
this.groupBox1.Controls.Add(this.tbxLutFilePathName);
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Controls.Add(this.btnStopFwUpdate);
this.groupBox1.Controls.Add(this.btnOpenLutFile);
this.groupBox1.Location = new System.Drawing.Point(278, 56);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(436, 153);
this.groupBox1.TabIndex = 28;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Lookup Table";
//
// tbxLutFilePathName
//
this.tbxLutFilePathName.Location = new System.Drawing.Point(104, 23);
this.tbxLutFilePathName.Name = "tbxLutFilePathName";
this.tbxLutFilePathName.ReadOnly = true;
this.tbxLutFilePathName.Size = new System.Drawing.Size(322, 20);
this.tbxLutFilePathName.TabIndex = 2;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(10, 26);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(63, 13);
this.label4.TabIndex = 1;
this.label4.Text = "Path Name:";
//
// btnOpenLutFile
//
this.btnOpenLutFile.Location = new System.Drawing.Point(310, 53);
this.btnOpenLutFile.Name = "btnOpenLutFile";
this.btnOpenLutFile.Size = new System.Drawing.Size(116, 26);
this.btnOpenLutFile.TabIndex = 0;
this.btnOpenLutFile.Text = "Open";
this.btnOpenLutFile.UseVisualStyleBackColor = true;
this.btnOpenLutFile.Click += new System.EventHandler(this.btnOpenLutFile_Click);
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(250, 223);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(101, 13);
this.label9.TabIndex = 30;
this.label9.Text = "UpdateTime [min:s]:";
//
// lblUpdateTime
//
this.lblUpdateTime.AutoSize = true;
this.lblUpdateTime.Location = new System.Drawing.Point(357, 223);
this.lblUpdateTime.Name = "lblUpdateTime";
this.lblUpdateTime.Size = new System.Drawing.Size(28, 13);
this.lblUpdateTime.TabIndex = 31;
this.lblUpdateTime.Text = "0:00";
//
// lblLutFileLoadedInfo
//
this.lblLutFileLoadedInfo.AutoSize = true;
this.lblLutFileLoadedInfo.Location = new System.Drawing.Point(10, 53);
this.lblLutFileLoadedInfo.Name = "lblLutFileLoadedInfo";
this.lblLutFileLoadedInfo.Size = new System.Drawing.Size(97, 13);
this.lblLutFileLoadedInfo.TabIndex = 9;
this.lblLutFileLoadedInfo.Text = "LUT file not loaded";
//
// FrmLutUpdate
//
this.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(723, 317);
this.Controls.Add(this.lblUpdateTime);
this.Controls.Add(this.label9);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.lblWaitingForMeterResponse);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.lblOverall);
this.Controls.Add(this.lblFwUpdateInfo);
this.Controls.Add(this.barSingleProgressUpdate);
this.Controls.Add(this.lblActualProcess);
this.Controls.Add(this.grpSetup);
this.Controls.Add(this.barOverallProgressUpdate);
this.Name = "FrmLutUpdate";
this.Text = "Metrology Lookup Table Update";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmLutUpdate_FormClosing);
this.Load += new System.EventHandler(this.FrmLutUpdate_Load);
this.grpSetup.ResumeLayout(false);
this.grpSetup.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.GroupBox grpSetup;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.Label lblConnectPcb;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox cbComSlot;
private System.Windows.Forms.Button btnDownloadLutFile;
private System.Windows.Forms.ProgressBar barOverallProgressUpdate;
private System.Windows.Forms.Timer tmrProgressUpdate;
private System.Windows.Forms.Label lblActualProcess;
private System.Windows.Forms.Label lblOverall;
private System.Windows.Forms.ProgressBar barSingleProgressUpdate;
private System.Windows.Forms.OpenFileDialog dlgOpenLuFile;
private System.Windows.Forms.Label lblFwUpdateInfo;
private System.Windows.Forms.Button btnStopFwUpdate;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.Label lblWaitingForMeterResponse;
private System.Windows.Forms.Label lblCoreRevision;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox tbxLutFilePathName;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Button btnOpenLutFile;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.Label lblUpdateTime;
private System.Windows.Forms.Label lblLutFileLoadedInfo;
}
}

View File

@ -0,0 +1,464 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
namespace Xylem.Common.Ui.GenesisToolBox
{
/// <summary>
/// FW update form
/// </summary>
public partial class FrmLutUpdate : Form
{
#region Variables
private readonly MeterBatch _meterBatch = new MeterBatch();
private GenesisMeter _currentGenesis;
private const String StrConnecting = "Connecting to PCB";
private const String StrNotConnected = "NOT CONNECTED";
private const String StrCoreRevision = "System Core Revision: ";
private const String StrPartPcbConnected = "Connected to PCB ID: ";
private const String StrOverallProcess = "Overall Process";
private MeterLutUpdate _meterLutUpdate;
private String _lastFwUpdateState;
private Int32 _lastSingleProgress;
private DateTimeOffset _startTime;
private Boolean _resetTimeMeasurement;
private readonly Boolean _updateGui = true;
private Boolean _lutFileValid;
private Boolean _tryConnectPcb;
private Boolean _lutFileSuccessfulWritten;
private const String StrUpdateErrorMessage = "METROLOGY LOOKUP TABLE UPDATE FAILED!\n\n";
private const String StrUpdateSuccessMessage = "Metrology lookup table successfulley written!\n\n";
private const String StrLutFileInvalid = "LUT FILE INVALID";
private const String StrLutFileValid = "LUT file loaded";
#endregion
#region FormControls
/// <summary>
/// Ctor FW update
/// </summary>
public FrmLutUpdate()
{
InitializeComponent();
var cultureInfo = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = cultureInfo;
}
/// <summary>
/// Clear data table and set genesis to not connected
/// </summary>
private void Init()
{
ProcessViewControl(false);
lblConnectPcb.Text = StrNotConnected;
lblCoreRevision.Text = "";
lblConnectPcb.ForeColor = Color.Red;
lblWaitingForMeterResponse.Visible = false;
btnConnect.Enabled = true;
btnDownloadLutFile.ForeColor = Color.DarkGreen;
btnStopFwUpdate.ForeColor = Color.Red;
SetControlDownloadsLocked();
btnStopFwUpdate.Enabled = false;
btnOpenLutFile.Enabled = true;
}
private void FrmLutUpdate_Load(Object sender, EventArgs e)
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
lblFwUpdateInfo.Text = $@"Version: {version.Major}.{version.Minor}.{version.Build}";
_resetTimeMeasurement = true;
Init();
}
private void FrmLutUpdate_FormClosing(Object sender, FormClosingEventArgs e)
{
_currentGenesis?.Logout();
_meterBatch?.RemoveAllMeters();
_meterBatch?.Dispose();
_meterLutUpdate?.Dispose();
_meterLutUpdate = null;
Dispose();
}
private void cbComSlot_SelectedIndexChanged(Object sender, EventArgs e)
{
_resetTimeMeasurement = true;
Init();
}
#endregion
#region ActivationControls
private void SetControlDownloadsLocked()
{
btnDownloadLutFile.Enabled = false;
btnStopFwUpdate.Enabled = false;
btnConnect.Enabled = true;
}
private void SetControlsDownloadIsOngoing()
{
btnConnect.Enabled = false;
btnOpenLutFile.Enabled = false;
btnDownloadLutFile.Enabled = false;
btnStopFwUpdate.Enabled = true;
}
private void SetControlsDownloadIsFinished()
{
_currentGenesis.RequestProtocol.AdditionalRetryTimeoutMs = 0;
btnConnect.Enabled = true;
btnOpenLutFile.Enabled = true;
btnDownloadLutFile.Enabled = true;
btnStopFwUpdate.Enabled = false;
}
#endregion
#region BoardControls
private void Connect()
{
try
{
Init();
Int32 slotNr;
if (string.IsNullOrEmpty(cbComSlot.SelectedItem.ToString()) ||
!int.TryParse(cbComSlot.SelectedItem.ToString(), out slotNr))
{
return;
}
_currentGenesis?.DisposeMeter();
//dispose old meter
_meterBatch.RemoveAllMeters();
_currentGenesis = null;
Thread.Sleep(200);
//assign new meter and assign meter to FW update file if this exists
_currentGenesis = new GenesisMeter();
_currentGenesis.SetupFromConfigFile(slotNr);
_meterBatch.AddMeter(_currentGenesis);
_currentGenesis._configuration.UseRegisterWatchService = false;
_currentGenesis._configuration.UseMinMaxCheck = false;
Task.Factory.StartNew(() =>
{
ViewProgressPcb(true);
_meterBatch.MetersLogin();
if (!_currentGenesis.IsLoggedOn)
{
Thread.Sleep(2000);
_meterBatch.MetersLogin();
}
if (!_currentGenesis.IsLoggedOn)
{
return;
}
_meterLutUpdate?.AssignGenesis(_currentGenesis);
Invoke(new Action(() =>
{
lblConnectPcb.Text = StrPartPcbConnected + _currentGenesis.PcbId;
lblCoreRevision.Text = StrCoreRevision + _currentGenesis.CoreRevision;
lblConnectPcb.ForeColor = Color.Green;
CheckUpdateEnabled();
_currentGenesis.Logout();
}));
}).ContinueWith(delegate { ViewProgressPcb(false); });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region ProcessControls
private void ViewProgressPcb(Boolean isActive)
{
if (_updateGui)
{
if (isActive)
{
Invoke(new Action(() =>
{
_tryConnectPcb = true;
ProcessViewControl(true);
lblActualProcess.Text = StrConnecting;
lblOverall.Text = StrOverallProcess;
}));
}
else
{
Invoke(new Action(() =>
{
_tryConnectPcb = false;
ProcessViewControl(false);
}));
}
}
}
/// <summary>
/// View all process bars and labels
/// </summary>
private void ProcessViewControl(Boolean view)
{
if (view)
{
lblActualProcess.Visible = true;
lblOverall.Visible = true;
barOverallProgressUpdate.Visible = true;
barSingleProgressUpdate.Visible = true;
_lastFwUpdateState = "";
tmrProgressUpdate.Enabled = true;
}
else
{
lblActualProcess.Visible = false;
lblOverall.Visible = false;
barOverallProgressUpdate.Visible = false;
barSingleProgressUpdate.Visible = false;
tmrProgressUpdate.Enabled = false;
_lastFwUpdateState = "";
lblWaitingForMeterResponse.Visible = false;
lblActualProcess.Text = "";
lblOverall.Text = "";
}
//common actions and settings
lblActualProcess.Update();
lblOverall.Update();
barOverallProgressUpdate.Value = 0;
barOverallProgressUpdate.Update();
barSingleProgressUpdate.Value = 0;
barSingleProgressUpdate.Update();
Update();
}
private void StartStopDownload(Boolean isActive)
{
if (isActive)
{
Invoke(new Action(() =>
{
_lastFwUpdateState = "";
ProcessViewControl(true);
tmrProgressUpdate.Enabled = true;
}));
}
else
{
Invoke(new Action(() =>
{
ProcessViewControl(false);
SetControlsDownloadIsFinished();
if (_lutFileSuccessfulWritten)
{
MessageBoxShow(StrUpdateErrorMessage, @"FAILED",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBoxShow(StrUpdateSuccessMessage, @"SUCCESS",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}));
}
}
#endregion
#region Checks
private void CheckUpdateEnabled()
{
//this check has been placed here to force display update
if (_meterLutUpdate != null && _currentGenesis != null && _lutFileValid)
{
SetControlDownloadsLocked();
return;
}
SetControlDownloadsLocked();
}
#endregion
#region TimerControls
private void tmrProgressUpdate_Tick(Object sender, EventArgs e)
{
//cbxManualControl.Visible = true;
if (_tryConnectPcb)
{
barOverallProgressUpdate.Value = barOverallProgressUpdate.Value + 1 > 100 ? 0 :
barOverallProgressUpdate.Value + 1;
barSingleProgressUpdate.Value = barSingleProgressUpdate.Value + 4 > 100 ? 0 :
barSingleProgressUpdate.Value + 4;
lblOverall.Text = StrOverallProcess;
}
else
{
lblOverall.Text = _meterLutUpdate?.GetLutUpdateStateOperation();
lblActualProcess.Text = _meterLutUpdate?.GetActualOperation();
var overallProgress = (Int32)(_meterLutUpdate?.OverallProcessCtrPercent ?? 0);
barOverallProgressUpdate.Value = overallProgress > 100 ? 100 : overallProgress;
barOverallProgressUpdate.Update();
var singleProgress = (Int32)(_meterLutUpdate?.SingleFileProcessCtrPercent ?? 0);
if (_meterLutUpdate?.GetLutUpdateStateOperation() != _lastFwUpdateState)
{
_lastFwUpdateState = _meterLutUpdate?.GetLutUpdateStateOperation();
lblWaitingForMeterResponse.Visible = false;
}
else
{
//if the communication gets frozen
lblWaitingForMeterResponse.Visible = _lastSingleProgress == singleProgress;
}
barSingleProgressUpdate.Value = singleProgress > 100 ? 100 : singleProgress;
_lastSingleProgress = singleProgress;
barSingleProgressUpdate.Update();
}
SetTimeDisplay();
Update();
}
private void SetTimeDisplay()
{
var time = DateTimeOffset.UtcNow;
var timeSpan = time - _startTime;
lblUpdateTime.Text = $@"{(UInt32)timeSpan.TotalMinutes}:{timeSpan.Seconds:00}";
}
#endregion
#region Buttons
private void btnConnect_Click(Object sender, EventArgs e)
{
if (_resetTimeMeasurement)
{
_startTime = DateTimeOffset.UtcNow;
_resetTimeMeasurement = false;
}
Connect();
}
private void btnOpenLutFile_Click(Object sender, EventArgs e)
{
if (dlgOpenLuFile.ShowDialog() != DialogResult.OK)
{
return;
}
var lutFilePathName = dlgOpenLuFile.FileName;
tbxLutFilePathName.Text = lutFilePathName;
if (_meterLutUpdate == null)
{
_meterLutUpdate = new MeterLutUpdate(_currentGenesis);
}
if (_meterLutUpdate == null)
{
return;
}
if (_meterLutUpdate.LoadLutFile(lutFilePathName))
{
lblLutFileLoadedInfo.ForeColor = Color.Green;
lblLutFileLoadedInfo.Text = StrLutFileValid;
_lutFileValid = true;
}
else
{
lblLutFileLoadedInfo.ForeColor = Color.Red;
lblLutFileLoadedInfo.Text = StrLutFileInvalid;
_lutFileValid = false;
}
CheckUpdateEnabled();
_resetTimeMeasurement = true;
}
/// <summary>
/// Download LUT file
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDownloadLutFile_Click(Object sender, EventArgs e)
{
if (_currentGenesis == null || _meterLutUpdate?.LutFile == null)
{
return;
}
SetControlsDownloadIsOngoing();
StartStopDownload(true);
_startTime = DateTimeOffset.UtcNow;
_resetTimeMeasurement = false;
Task.Factory.StartNew(() =>
{
_lutFileSuccessfulWritten = _meterLutUpdate.UpdateMeterLut();
Thread.Sleep(1000);
}).ContinueWith(delegate { StartStopDownload(false); });
}
private void btnStopFwUpdate_Click(Object sender, EventArgs e)
{
if (_meterLutUpdate != null)
{
_meterLutUpdate.StopUpdateProcess = true;
}
}
#endregion
#region ExternalCalls
public MsgEventArgs LastMsgEvent;
public class MsgEventArgs : EventArgs
{
public String Text;
public String Caption;
public MessageBoxButtons Buttons;
public MessageBoxIcon Icon;
}
public event EventHandler<MsgEventArgs> OnMsgPopUp;
private void MessageBoxShow(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{
if (_updateGui)
{
MessageBox.Show(text, caption, buttons, icon);
}
else
{
LastMsgEvent = new MsgEventArgs() { Text = text, Caption = caption, Buttons = buttons, Icon = icon };
OnMsgPopUp?.Invoke(this, LastMsgEvent);
}
}
#endregion
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="tmrProgressUpdate.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>274, 17</value>
</metadata>
<metadata name="dlgOpenLuFile.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>144, 17</value>
</metadata>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>432, 17</value>
</metadata>
</root>

View File

@ -194,6 +194,12 @@
<Compile Include="FrmFrozenMeter.Designer.cs">
<DependentUpon>FrmFrozenMeter.cs</DependentUpon>
</Compile>
<Compile Include="FrmLutUpdate.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmLutUpdate.Designer.cs">
<DependentUpon>FrmLutUpdate.cs</DependentUpon>
</Compile>
<Compile Include="FrmFwUpdate.cs">
<SubType>Form</SubType>
</Compile>
@ -338,6 +344,10 @@
<EmbeddedResource Include="FrmFrozenMeter.resx">
<DependentUpon>FrmFrozenMeter.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FrmLutUpdate.resx">
<DependentUpon>FrmLutUpdate.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="FrmFwUpdate.resx">
<DependentUpon>FrmFwUpdate.cs</DependentUpon>
<SubType>Designer</SubType>

View File

@ -49,6 +49,7 @@
this.BtnFileSplit = new System.Windows.Forms.Button();
this.btnFiles = new System.Windows.Forms.Button();
this.btnLegacyTestApp = new System.Windows.Forms.Button();
this.btnLutUpdate = new System.Windows.Forms.Button();
this.gpGerneral.SuspendLayout();
this.gpLAA.SuspendLayout();
this.gbDeveloper.SuspendLayout();
@ -56,6 +57,7 @@
//
// gpGerneral
//
this.gpGerneral.Controls.Add(this.btnLutUpdate);
this.gpGerneral.Controls.Add(this.button1);
this.gpGerneral.Controls.Add(this.btnFreeze);
this.gpGerneral.Controls.Add(this.btnConfiguration);
@ -69,14 +71,14 @@
this.gpGerneral.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpGerneral.Location = new System.Drawing.Point(13, 12);
this.gpGerneral.Name = "gpGerneral";
this.gpGerneral.Size = new System.Drawing.Size(181, 449);
this.gpGerneral.Size = new System.Drawing.Size(181, 503);
this.gpGerneral.TabIndex = 19;
this.gpGerneral.TabStop = false;
this.gpGerneral.Text = "General";
//
// button1
//
this.button1.Location = new System.Drawing.Point(5, 411);
this.button1.Location = new System.Drawing.Point(4, 455);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(152, 40);
this.button1.TabIndex = 16;
@ -87,7 +89,7 @@
// btnFreeze
//
this.btnFreeze.Enabled = false;
this.btnFreeze.Location = new System.Drawing.Point(6, 365);
this.btnFreeze.Location = new System.Drawing.Point(5, 409);
this.btnFreeze.Name = "btnFreeze";
this.btnFreeze.Size = new System.Drawing.Size(152, 40);
this.btnFreeze.TabIndex = 15;
@ -97,7 +99,7 @@
//
// btnConfiguration
//
this.btnConfiguration.Location = new System.Drawing.Point(6, 321);
this.btnConfiguration.Location = new System.Drawing.Point(5, 365);
this.btnConfiguration.Name = "btnConfiguration";
this.btnConfiguration.Size = new System.Drawing.Size(152, 40);
this.btnConfiguration.TabIndex = 14;
@ -108,7 +110,7 @@
// btnCalender
//
this.btnCalender.Enabled = false;
this.btnCalender.Location = new System.Drawing.Point(6, 278);
this.btnCalender.Location = new System.Drawing.Point(5, 322);
this.btnCalender.Name = "btnCalender";
this.btnCalender.Size = new System.Drawing.Size(151, 39);
this.btnCalender.TabIndex = 13;
@ -169,7 +171,7 @@
//
// btnSetup
//
this.btnSetup.Location = new System.Drawing.Point(5, 15);
this.btnSetup.Location = new System.Drawing.Point(6, 15);
this.btnSetup.Name = "btnSetup";
this.btnSetup.Size = new System.Drawing.Size(152, 40);
this.btnSetup.TabIndex = 1;
@ -290,18 +292,28 @@
this.btnLegacyTestApp.UseVisualStyleBackColor = true;
this.btnLegacyTestApp.Click += new System.EventHandler(this.btnLegacyTestApp_Click);
//
// btnLutUpdate
//
this.btnLutUpdate.Location = new System.Drawing.Point(7, 279);
this.btnLutUpdate.Name = "btnLutUpdate";
this.btnLutUpdate.Size = new System.Drawing.Size(151, 39);
this.btnLutUpdate.TabIndex = 17;
this.btnLutUpdate.Text = "Metrology Lookup Table Download";
this.btnLutUpdate.UseVisualStyleBackColor = true;
this.btnLutUpdate.Click += new System.EventHandler(this.btnLutUpdate_Click);
//
// FrmMainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(390, 457);
this.ClientSize = new System.Drawing.Size(390, 517);
this.Controls.Add(this.gbDeveloper);
this.Controls.Add(this.gpLAA);
this.Controls.Add(this.gpGerneral);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(410, 500);
this.MinimumSize = new System.Drawing.Size(410, 500);
this.MaximumSize = new System.Drawing.Size(410, 560);
this.MinimumSize = new System.Drawing.Size(410, 560);
this.Name = "FrmMainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Genesis ToolBox";
@ -336,6 +348,7 @@
private System.Windows.Forms.Button btnLegacyTestApp;
private System.Windows.Forms.Button btnFreeze;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button btnLutUpdate;
}
}

View File

@ -331,5 +331,13 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
}
private void btnLutUpdate_Click(object sender, EventArgs e)
{
var form = new FrmLutUpdate();
form.Show();
form.Closed += Form_Closed;
Hide();
}
}
}

View File

@ -4432,7 +4432,7 @@ namespace Xylem.ServiceFwUpdate.Ui.FwUpdateBuilder
/// <summary>
/// Get the content of one selected FW update report from DB.
/// </summary>
/// <param name="report">report filled with content</param>
/// <param name="reportDb">report filled with content</param>
/// <param name="pcbId"></param>
/// <param name="userId"></param>
/// <param name="orderNo"></param>

View File

@ -58,10 +58,10 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>D8B4896173CF7130DF43C53CECCE6E4A7595CA5C</ManifestCertificateThumbprint>
<ManifestCertificateThumbprint>3D39BF7375F751B96081DE64F2A442ABD8A73321</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>FwUpdateBuilder_TemporaryKey.pfx</ManifestKeyFile>
<ManifestKeyFile>FwUpdateBuilder_1_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
@ -161,6 +161,7 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="FwUpdateBuilder_1_TemporaryKey.pfx" />
<None Include="FwUpdateBuilder_TemporaryKey.pfx" />
<None Include="MeterFwUpdateRuler.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@ -58,10 +58,10 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>550FE4A801FCFB0A36EB3B198C4A6E6A92020511</ManifestCertificateThumbprint>
<ManifestCertificateThumbprint>5ED6B0B9BFFE7DD309362274CB9BF34BAE31CEEE</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>FwUpdateLoader_TemporaryKey.pfx</ManifestKeyFile>
<ManifestKeyFile>FwUpdateLoader_1_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
@ -146,6 +146,7 @@
<DependentUpon>Resources.de.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="FwUpdateLoader_1_TemporaryKey.pfx" />
<None Include="FwUpdateLoader_TemporaryKey.pfx" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">