4305 lines
218 KiB
C#
4305 lines
218 KiB
C#
using System.Collections;
|
|
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
using GlobalIPerlUtility;
|
|
using Microsoft.VisualBasic;
|
|
using NA2WNFC;
|
|
using NfcC7_DLL.NfcHanler.FieldLogicStaging;
|
|
using NfcC7_DLL.NfcHanler.FieldLogicStaging.GlobalIPerlTags;
|
|
using NfcC7_DLL.NfcHanler.FieldLogicStaging.SterlingMetrologyTags;
|
|
using NfcC7_DLL.NfcHanler.Utils;
|
|
using Sensus;
|
|
using Sensus.Protocols.FlexNet;
|
|
using Sensus.Protocols.FlexNet.FNv2;
|
|
using Sensus.Protocols.FlexNet.FNv2.NA2WParameters;
|
|
using Sensus.Protocols.FlexNet.Serial;
|
|
using Sensus.Protocols.FlexNet.Serial.FNv2;
|
|
using Log = NfcC7_DLL.NfcHanler.Utils.Log;
|
|
using MeterSize = NfcC7_DLL.NfcHanler.FieldLogicStaging.SterlingMetrologyTags.MeterSize;
|
|
using NA2WProductType = NfcC7_DLL.NfcHanler.FieldLogicStaging.NA2WProductType;
|
|
using NfcCommand_InventoryRead = NfcC7_DLL.NfcHanler.Protocols.NfcCommand_InventoryRead;
|
|
using NfcCommand_NdefRead = NfcC7_DLL.NfcHanler.Protocols.NfcCommand_NdefRead;
|
|
using Ping_NA2WDataReport_NA2WWater_TimeValues = Sensus.Protocols.FlexNet.Ping_NA2WDataReport_NA2WWater_TimeValues;
|
|
using TemperatureCalibration = NfcC7_DLL.NfcHanler.FieldLogicStaging.GlobalIPerlTags.TemperatureCalibration;
|
|
|
|
namespace NfcC7_DLL.NfcHanler
|
|
{
|
|
public class MessageEngine
|
|
{
|
|
private const byte WIDTH_MASK = 0x07;
|
|
|
|
private WindowViewModel windowViewModel = null;
|
|
private ISerialConnection serialManager = null;
|
|
string currentFilename = "";
|
|
DateTime lastCSVExport;
|
|
private UInt16 sessionId = 0;
|
|
StringBuilder csvString;
|
|
|
|
public MessageEngine()
|
|
{
|
|
receiveQueue = new BlockingQueue<FrameEventArgs<IFrame>>();
|
|
|
|
eventThread = ThreadHelpers.MakeThread("FrameEventLoop", FrameEventLoop);
|
|
eventThread.IsBackground = true;
|
|
eventThread.Start();
|
|
}
|
|
|
|
public WindowViewModel ViewModel
|
|
{
|
|
set
|
|
{
|
|
windowViewModel = value;
|
|
|
|
SetComPortList(GetPortNames());
|
|
|
|
windowViewModel.LogWithDescription = true;
|
|
windowViewModel.LogWithHexString = true;
|
|
windowViewModel.LogChargingData = false;
|
|
}
|
|
}
|
|
|
|
public void OpenClose()
|
|
{
|
|
if (windowViewModel.IsOpen)
|
|
{
|
|
if (serialManager is NfcReader)
|
|
{
|
|
NfcReader nfcReader = (NfcReader)serialManager;
|
|
nfcReader.TagEvent -= NfcReader_TagEvent;
|
|
}
|
|
else if (serialManager is CmdLinkGen2Link)
|
|
{
|
|
CmdLinkGen2Link cmdLinkGen2Link = (CmdLinkGen2Link)serialManager;
|
|
cmdLinkGen2Link.TagEvent -= NfcReader_TagEvent;
|
|
}
|
|
else if (serialManager is MeterTestHatLink)
|
|
{
|
|
MeterTestHatLink meterTestHatLink = (MeterTestHatLink)serialManager;
|
|
meterTestHatLink.TagEvent -= NfcReader_TagEvent;
|
|
}
|
|
|
|
serialManager.Close();
|
|
serialManager = null;
|
|
|
|
windowViewModel.IsOpen = false;
|
|
}
|
|
else
|
|
{
|
|
String comPortString = windowViewModel.ComPortSelectedItem;
|
|
|
|
try
|
|
{
|
|
if (windowViewModel.LinkSelectedItem == "NFC Reader")
|
|
{
|
|
NfcReader nfcReader = new NfcReader(windowViewModel.ComPortSelectedItem);
|
|
nfcReader.TagEvent += NfcReader_TagEvent;
|
|
|
|
serialManager = nfcReader;
|
|
}
|
|
else if (windowViewModel.LinkSelectedItem == "CmdLink II")
|
|
{
|
|
CmdLinkGen2Link cmdLink2Link = new CmdLinkGen2Link(windowViewModel.ComPortSelectedItem);
|
|
cmdLink2Link.TagEvent += NfcReader_TagEvent;
|
|
serialManager = cmdLink2Link;
|
|
}
|
|
else if (windowViewModel.LinkSelectedItem == "Meter Test Hat")
|
|
{
|
|
MeterTestHatLink meterTestHatLink = new MeterTestHatLink(windowViewModel.ComPortSelectedItem);
|
|
meterTestHatLink.TagEvent += NfcReader_TagEvent;
|
|
serialManager = meterTestHatLink;
|
|
}
|
|
else
|
|
{
|
|
serialManager = new SerialManager(windowViewModel.ComPortSelectedItem);
|
|
}
|
|
|
|
serialManager.Open();
|
|
|
|
if (serialManager.IsConnected)
|
|
{
|
|
serialManager.MessageReceived += MessageReceived;
|
|
windowViewModel.IsOpen = true;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
serialManager = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void NfcReader_TagEvent(object sender, TagEventArgs e)
|
|
{
|
|
//viewModel.NfcTagDetected = e.Present;
|
|
if ((e.Present ) && (serialManager is NfcReader))
|
|
{
|
|
NfcReader nfcReader = (NfcReader)serialManager;
|
|
NfcTargetDetails nfcTargetDetails = nfcReader.NfcTargetDetails;
|
|
|
|
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
|
|
{
|
|
windowViewModel.ResetValues();
|
|
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
|
|
Byte productType = 0;
|
|
Byte.TryParse(nfcTargetDetails.ProductType, out productType);
|
|
windowViewModel.ProductType = productType;
|
|
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
|
|
}
|
|
}
|
|
else if ((e.Present) && (serialManager is CmdLinkGen2Link))
|
|
{
|
|
CmdLinkGen2Link cmdLinkGen2Link = (CmdLinkGen2Link)serialManager;
|
|
NfcTargetDetails nfcTargetDetails = cmdLinkGen2Link.NfcTargetDetails;
|
|
|
|
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
|
|
{
|
|
windowViewModel.ResetValues();
|
|
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
|
|
Byte productType = 0;
|
|
Byte.TryParse(nfcTargetDetails.ProductType, out productType);
|
|
windowViewModel.ProductType = productType;
|
|
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
|
|
}
|
|
}
|
|
else if ((e.Present) && (serialManager is MeterTestHatLink))
|
|
{
|
|
MeterTestHatLink meterTestHatLink = (MeterTestHatLink)serialManager;
|
|
NfcTargetDetails nfcTargetDetails = meterTestHatLink.NfcTargetDetails;
|
|
|
|
if (nfcTargetDetails.DeviceId != windowViewModel.DeviceId)
|
|
{
|
|
windowViewModel.ResetValues();
|
|
windowViewModel.DeviceId = nfcTargetDetails.DeviceId;
|
|
Byte productType = 0;
|
|
Byte.TryParse(nfcTargetDetails.ProductType, NumberStyles.HexNumber, null, out productType);
|
|
windowViewModel.ProductType = productType;
|
|
windowViewModel.ProductTypeVersion = nfcTargetDetails.ProductVersion;
|
|
|
|
Utility.Log.Write(String.Format("Found NFC tag {0} (PT: {1}, PV: {2}, ID: {3}).", nfcTargetDetails.TagId, productType, nfcTargetDetails.ProductVersion, nfcTargetDetails.DeviceId));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void Link(String command)
|
|
{
|
|
String[] cmdArgs = command.Split(new char[] { ' ' }, 2);
|
|
|
|
if (cmdArgs[0].Equals("PortRefresh"))
|
|
{
|
|
if (windowViewModel.LinkSelectedItem == "NFC Reader")
|
|
{
|
|
SetComPortList(NFCReader.GetAvailableReaders().ToArray());
|
|
windowViewModel.IsNfcFeaturesEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
SetComPortList(GetPortNames());
|
|
windowViewModel.IsNfcFeaturesEnabled = (windowViewModel.LinkSelectedItem == "CmdLink II") || (windowViewModel.LinkSelectedItem == "Meter Test Hat");
|
|
}
|
|
}
|
|
else if (cmdArgs[0].Equals("NfcRefresh"))
|
|
{
|
|
if (serialManager is NfcReader reader && reader.IsConnected)
|
|
{
|
|
byte[] ndefData = reader.Get_Ndef_Data();
|
|
byte[] ramData = reader.Get_RMA_Data();
|
|
windowViewModel.NfcNdefParseText = $"NDEF Records:\n{ndefData.ToHexString()}\n";
|
|
foreach (NdefRecord record in reader.GetNdefRecords())
|
|
{
|
|
windowViewModel.NfcNdefParseText += record.Payload.ToString();
|
|
}
|
|
GlobalIPerlRma esaapPomNfcRma = new GlobalIPerlRma(ramData);
|
|
windowViewModel.NfcRmaParseText = esaapPomNfcRma.ToString();
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum EngineerTestCommandList
|
|
{
|
|
WdReset = 0x00, /// Watchdog Reset Test
|
|
PulseOut = 0x01, /// Pulse out test
|
|
TxBup = 0x02, /// Transmit Activity BUP
|
|
DisplaySwitchOpen = 0x03, /// Generate Display Switch Open event
|
|
DisplaySwitchClose = 0x04, /// Generate Display Switch Close event
|
|
PowerSwitch = 0x05, /// Power Domain Control
|
|
ComaSleep = 0x06, /// Enter Coma Sleep, power down all power domains
|
|
ExternalFlashTest = 0x07, /// External flash write/read test
|
|
NfcEepromTest = 0x08, /// NFC EEPROM write/read test
|
|
OpticalLedToggle = 0x09, /// Toggle optical data LED on
|
|
TxPeriodicReading = 0x0A, /// Start or stop transmission of a periodic reading
|
|
}
|
|
|
|
public void Read(string tagDescription)
|
|
{
|
|
List<byte> GlobalIPerlTag = new List<byte>();
|
|
|
|
if (tagDescription.Length != 0)
|
|
{
|
|
string[] tag = tagDescription.Split(',');
|
|
|
|
for (int i = 0; i < tag.Length; i++)
|
|
{
|
|
GlobalIPerlTag GlobalIPerlTagItem;
|
|
if (Enum.TryParse(tag[i], true, out GlobalIPerlTagItem))
|
|
{
|
|
System.Console.WriteLine((int)GlobalIPerlTagItem);
|
|
|
|
GlobalIPerlTag.Add((byte)GlobalIPerlTagItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GlobalIPerlTag.Count != 0)
|
|
{
|
|
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, GlobalIPerlTag);
|
|
SendNa2wSerial(parameterReadCommand, false);
|
|
}
|
|
}
|
|
|
|
public void ReadSterling(string tagDescription)
|
|
{
|
|
List<byte> GlobalIPerlTag = new List<byte>();
|
|
|
|
if (tagDescription.Length != 0)
|
|
{
|
|
string[] tag = tagDescription.Split(',');
|
|
|
|
for (int i = 0; i < tag.Length; i++)
|
|
{
|
|
SterlingMetrologyTag GlobalIPerlTagItem;
|
|
if (Enum.TryParse(tag[i], true, out GlobalIPerlTagItem))
|
|
{
|
|
System.Console.WriteLine((int)GlobalIPerlTagItem);
|
|
|
|
GlobalIPerlTag.Add((byte)GlobalIPerlTagItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GlobalIPerlTag.Count != 0)
|
|
{
|
|
ParameterReadCommand parameterReadCommand = new ParameterReadCommand((TagMap)0x05, GlobalIPerlTag);
|
|
SendNa2wSerial(parameterReadCommand, false);
|
|
}
|
|
}
|
|
|
|
|
|
public void Write(string tagDescription)
|
|
{
|
|
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
|
|
List<byte> tagReadList = new List<byte>();
|
|
|
|
if (tagDescription.Length != 0)
|
|
{
|
|
string[] tags = tagDescription.Split(',');
|
|
|
|
for (int i = 0; i < tags.Length; i++)
|
|
{
|
|
string tag = tags[i];
|
|
|
|
if (tag.Equals("SerialNumber"))
|
|
{
|
|
if (windowViewModel.SerialNumberNew.Length != 0)
|
|
{
|
|
UInt64 value = UInt64.Parse(windowViewModel.SerialNumberNew);
|
|
SerialNumber serialNumber = new SerialNumber(value);
|
|
na2wParamList.Add(serialNumber);
|
|
}
|
|
}
|
|
else if (tag.Equals("RfPowerLevel"))
|
|
{
|
|
Byte powerLevel;
|
|
|
|
if (Conversion.TryParseHexOrDecString(windowViewModel.RfPowerLevelNew, out powerLevel))
|
|
{
|
|
RfPowerLevel paPowerLevel = new RfPowerLevel();
|
|
paPowerLevel.PowerLevel = powerLevel;
|
|
na2wParamList.Add(paPowerLevel);
|
|
}
|
|
}
|
|
else if (tag.Equals("DeviceId"))
|
|
{
|
|
UInt32 id;
|
|
|
|
if (
|
|
(windowViewModel.DeviceIdNew.Length != 0)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out id)
|
|
)
|
|
{
|
|
DeviceId deviceId = new DeviceId();
|
|
deviceId.Id = id;
|
|
na2wParamList.Add(deviceId);
|
|
}
|
|
}
|
|
else if (tag.Equals("TcxoCorrection"))
|
|
{
|
|
System.Console.WriteLine(tagDescription + " = " + windowViewModel.TcxoCorrectionNew);
|
|
Int16 correction;
|
|
|
|
if (
|
|
(windowViewModel.TcxoCorrectionNew.Length != 0)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.TcxoCorrectionNew, out correction)
|
|
)
|
|
{
|
|
TcxoCorrection tcxoCorrection = new TcxoCorrection();
|
|
tcxoCorrection.Correction = correction;
|
|
na2wParamList.Add(tcxoCorrection);
|
|
}
|
|
}
|
|
else if (tag.Equals("TemperatureCalibration"))
|
|
{
|
|
SByte calOffset;
|
|
|
|
if (
|
|
(windowViewModel.TemperatureCalOffsetNew.Length != 0)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.TemperatureCalOffsetNew, out calOffset)
|
|
)
|
|
{
|
|
TemperatureCalibration temperatureCalibration = new TemperatureCalibration();
|
|
temperatureCalibration.CalOffset = calOffset;
|
|
na2wParamList.Add(temperatureCalibration);
|
|
|
|
// Update corrected temperature
|
|
tagReadList.Add((byte)GlobalIPerlTag.Temperature);
|
|
}
|
|
}
|
|
else if (tag.Equals("VbatCalibration"))
|
|
{
|
|
SByte calOffset;
|
|
UInt16 calSlope;
|
|
|
|
if (
|
|
Conversion.TryParseHexOrDecString(windowViewModel.VbatCalOffsetNew, out calOffset)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.VbatCalSlopeNew, out calSlope)
|
|
)
|
|
{
|
|
VbatCalibration vbatCalibration = new VbatCalibration();
|
|
vbatCalibration.CalOffset = calOffset;
|
|
vbatCalibration.CalSlope = calSlope;
|
|
na2wParamList.Add(vbatCalibration);
|
|
|
|
// Update corrected Vbat
|
|
tagReadList.Add((byte)GlobalIPerlTag.Vbat);
|
|
}
|
|
}
|
|
else if (tag.Equals("VsysCalibration"))
|
|
{
|
|
SByte calOffset;
|
|
UInt16 calSlope;
|
|
|
|
if (
|
|
Conversion.TryParseHexOrDecString(windowViewModel.VsysCalOffsetNew, out calOffset)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.VsysCalSlopeNew, out calSlope)
|
|
)
|
|
{
|
|
VsysCalibration vsysCalibration = new VsysCalibration();
|
|
vsysCalibration.CalOffset = calOffset;
|
|
vsysCalibration.CalSlope = calSlope;
|
|
na2wParamList.Add(vsysCalibration);
|
|
|
|
// Update corrected Vsys
|
|
tagReadList.Add((byte)GlobalIPerlTag.Vsys);
|
|
}
|
|
}
|
|
else if (tag.Equals("ManufacturingNote"))
|
|
{
|
|
string note = windowViewModel.ManufacturingNoteNew;
|
|
if (note.Length > 64)
|
|
{
|
|
note = note.Substring(0, 64);
|
|
}
|
|
|
|
ManufacturingNote manufacturingNote = new ManufacturingNote();
|
|
manufacturingNote.NoteParsed = note;
|
|
na2wParamList.Add(manufacturingNote);
|
|
}
|
|
else if (tag.Equals("RHumidCalOffset"))
|
|
{
|
|
SByte calOffset;
|
|
|
|
if (
|
|
(windowViewModel.RHumidCalOffsetNew.Length != 0)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.RHumidCalOffsetNew, out calOffset)
|
|
)
|
|
{
|
|
HumidityCalibration rHumidCalibration = new HumidityCalibration();
|
|
rHumidCalibration.CalOffset = calOffset;
|
|
na2wParamList.Add(rHumidCalibration);
|
|
|
|
// Update corrected humidity
|
|
tagReadList.Add((byte)GlobalIPerlTag.RHumid);
|
|
tagReadList.Add((byte)GlobalIPerlTag.RHumidCalOffset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (na2wParamList.Count != 0)
|
|
{
|
|
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
|
|
|
|
SendNa2wSerial(parameterWriteCommand, false);
|
|
}
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
if (tagReadList.Count != 0)
|
|
{
|
|
ParameterReadCommand parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
|
|
SendNa2wSerial(parameterReadCommand, false);
|
|
}
|
|
}
|
|
|
|
public void WriteSterling(string tagDescription)
|
|
{
|
|
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
|
|
List<byte> tagReadList = new List<byte>();
|
|
|
|
if (tagDescription.Length != 0)
|
|
{
|
|
string[] tags = tagDescription.Split(',');
|
|
|
|
for (int i = 0; i < tags.Length; i++)
|
|
{
|
|
string tag = tags[i];
|
|
|
|
if (tag.Equals("FactoryId"))
|
|
{
|
|
FactoryId factoryId =
|
|
new FactoryId();
|
|
factoryId.FactoryID = windowViewModel.FactoryIdNew;
|
|
na2wParamList.Add(factoryId);
|
|
}
|
|
|
|
if (tag.Equals("CustomerId"))
|
|
{
|
|
CustomerId customerId =
|
|
new CustomerId();
|
|
customerId.CustomerID = windowViewModel.CustomerIdNew;
|
|
na2wParamList.Add(customerId);
|
|
}
|
|
|
|
if (tag.Equals("BuildInfo"))
|
|
{
|
|
BuildInformation buildInfo =
|
|
new BuildInformation();
|
|
buildInfo.BuildInfo = windowViewModel.BuildInfoNew;
|
|
na2wParamList.Add(buildInfo);
|
|
}
|
|
|
|
if (tag.Equals("ManufactureDate"))
|
|
{
|
|
ManufactureDate manufactureDate =
|
|
new ManufactureDate();
|
|
manufactureDate.Date = windowViewModel.ManufactureDateNew;
|
|
na2wParamList.Add(manufactureDate);
|
|
}
|
|
|
|
if (tag.Equals("MeterState"))
|
|
{
|
|
MeterState meterState =
|
|
new MeterState();
|
|
meterState.Mode = windowViewModel.SterlingMeterStateNew;
|
|
na2wParamList.Add(meterState);
|
|
}
|
|
|
|
if (tag.Equals("OpticalDataMode"))
|
|
{
|
|
OpticalDataMode opticalDataMode =
|
|
new OpticalDataMode();
|
|
opticalDataMode.Mode = windowViewModel.OpticalDataModeNew;
|
|
|
|
na2wParamList.Add(opticalDataMode);
|
|
}
|
|
|
|
if (tag.Equals("DisplayTimeout"))
|
|
{
|
|
if (windowViewModel.DisplayTimeout.Length != 0)
|
|
{
|
|
DisplayTimeout displayTimeoutSet =
|
|
new DisplayTimeout();
|
|
displayTimeoutSet.Timeout = Byte.Parse(windowViewModel.DisplayTimeoutNew);
|
|
na2wParamList.Add(displayTimeoutSet);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("ASICTemperatureCalibration"))
|
|
{
|
|
Int16 calibration;
|
|
|
|
if (
|
|
(windowViewModel.ASICTemperatureCalibrationNew.Length != 0)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.ASICTemperatureCalibrationNew, out calibration)
|
|
)
|
|
{
|
|
TemperatureCalibration tempCal =
|
|
new TemperatureCalibration();
|
|
tempCal.TemperatureCal = calibration;
|
|
na2wParamList.Add(tempCal);
|
|
|
|
// Update corrected temperature
|
|
tagReadList.Add((byte)SterlingMetrologyTag.Temperature);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("EmptyPipeParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.EPParam_ImpedanceThresholdNew.Length != 0)
|
|
&& (windowViewModel.EPParam_EmptyTimeThresholdNew.Length != 0)
|
|
&& (windowViewModel.EPParam_HydrationDurationNew.Length != 0)
|
|
)
|
|
{
|
|
EmptyPipeParameters emptyPipeParameters =
|
|
new EmptyPipeParameters();
|
|
emptyPipeParameters.ImpedanceThreshold = UInt16.Parse(windowViewModel.EPParam_ImpedanceThresholdNew);
|
|
emptyPipeParameters.EmptyTimeThreshold = Byte.Parse(windowViewModel.EPParam_EmptyTimeThresholdNew);
|
|
emptyPipeParameters.HydrationDuration_hr = Byte.Parse(windowViewModel.EPParam_HydrationDurationNew);
|
|
na2wParamList.Add(emptyPipeParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("MagneticTamperParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.MTParam_MaxPercentErrorNew.Length != 0)
|
|
&& (windowViewModel.MTParam_DetectionCountsNew.Length != 0)
|
|
&& (windowViewModel.MTParam_PidSettlingTimeNew.Length != 0)
|
|
&& (windowViewModel.MTParam_DriveLowNew.Length != 0)
|
|
&& (windowViewModel.MTParam_DriveHighNew.Length != 0)
|
|
)
|
|
{
|
|
MagneticTamperParameters magneticTamperParameters =
|
|
new MagneticTamperParameters();
|
|
magneticTamperParameters.MaxPercentError = Byte.Parse(windowViewModel.MTParam_MaxPercentErrorNew);
|
|
magneticTamperParameters.DetectionCounts = Byte.Parse(windowViewModel.MTParam_DetectionCountsNew);
|
|
magneticTamperParameters.PidSettlingTime_s = Byte.Parse(windowViewModel.MTParam_PidSettlingTimeNew);
|
|
magneticTamperParameters.DriveLow = Byte.Parse(windowViewModel.MTParam_DriveLowNew);
|
|
magneticTamperParameters.DriveHigh = Byte.Parse(windowViewModel.MTParam_DriveHighNew);
|
|
na2wParamList.Add(magneticTamperParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("ReverseVolumeBufferParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.RVBParam_Threshold_qmlNew.Length != 0)
|
|
&& (windowViewModel.RVBParam_Leak_qml_sNew.Length != 0)
|
|
)
|
|
{
|
|
ReverseVolumeBufferParameters reverseVolumeBufferParameters =
|
|
new ReverseVolumeBufferParameters();
|
|
reverseVolumeBufferParameters.Threshold_qml = UInt32.Parse(windowViewModel.RVBParam_Threshold_qmlNew);
|
|
reverseVolumeBufferParameters.Leak_qml_s = UInt16.Parse(windowViewModel.RVBParam_Leak_qml_sNew);
|
|
na2wParamList.Add(reverseVolumeBufferParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("MagneticFieldDriveParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.MFDParam_DriveTimeNew.Length != 0)
|
|
&& (windowViewModel.MFDParam_FieldFitA0New.Length != 0)
|
|
&& (windowViewModel.MFDParam_FieldFitA1New.Length != 0)
|
|
&& (windowViewModel.MFDParam_FieldDriveStepMagnitudeNew.Length != 0)
|
|
&& (windowViewModel.MFDParam_FieldControlHysteresis_mGNew.Length != 0)
|
|
)
|
|
{
|
|
MagneticFieldDriveParameters magneticFieldDriveParameters =
|
|
new MagneticFieldDriveParameters();
|
|
magneticFieldDriveParameters.DriveTime = Byte.Parse(windowViewModel.MFDParam_DriveTimeNew);
|
|
magneticFieldDriveParameters.FieldFitA0 = Int32.Parse(windowViewModel.MFDParam_FieldFitA0New);
|
|
magneticFieldDriveParameters.FieldFitA1 = Int32.Parse(windowViewModel.MFDParam_FieldFitA1New);
|
|
magneticFieldDriveParameters.FieldDriveStepMagnitude = UInt16.Parse(windowViewModel.MFDParam_FieldDriveStepMagnitudeNew);
|
|
magneticFieldDriveParameters.FieldControlHysteresis_mG = UInt16.Parse(windowViewModel.MFDParam_FieldControlHysteresis_mGNew);
|
|
na2wParamList.Add(magneticFieldDriveParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("InputRangeParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.IRParam_AdcRailingHighThresholdNew.Length != 0)
|
|
&& (windowViewModel.IRParam_AdcRailingLowThresholdNew.Length != 0)
|
|
&& (windowViewModel.IRParam_MaxAdcThresholdNew.Length != 0)
|
|
&& (windowViewModel.IRParam_MaxElectrodeDeltaNew.Length != 0)
|
|
&& (windowViewModel.IRParam_EmfAlarmHoldoffHoursNew.Length != 0)
|
|
&& (windowViewModel.IRParam_AdcNoiseThresholdNew.Length != 0)
|
|
&& (windowViewModel.IRParam_RawImpedanceClampNew.Length != 0)
|
|
&& (windowViewModel.IRParam_MaxFlowRateNew.Length != 0)
|
|
&& (windowViewModel.IRParam_MaxFlowRateAlarmCountNew.Length != 0)
|
|
&& (windowViewModel.IRParam_FlowRateStdDevInvSlopeNew.Length != 0)
|
|
)
|
|
{
|
|
InputRangeParameters inputRangeParameters =
|
|
new InputRangeParameters();
|
|
inputRangeParameters.AdcRailingHighThreshold = UInt32.Parse(windowViewModel.IRParam_AdcRailingHighThresholdNew);
|
|
inputRangeParameters.AdcRailingLowThreshold = UInt32.Parse(windowViewModel.IRParam_AdcRailingLowThresholdNew);
|
|
inputRangeParameters.MaxAdcThreshold = UInt32.Parse(windowViewModel.IRParam_MaxAdcThresholdNew);
|
|
inputRangeParameters.MaxElectrodeDelta = UInt16.Parse(windowViewModel.IRParam_MaxElectrodeDeltaNew);
|
|
inputRangeParameters.EmfAlarmHoldoffHours = Byte.Parse(windowViewModel.IRParam_EmfAlarmHoldoffHoursNew);
|
|
inputRangeParameters.AdcNoiseThreshold = UInt16.Parse(windowViewModel.IRParam_AdcNoiseThresholdNew);
|
|
inputRangeParameters.RawImpedanceClamp = UInt32.Parse(windowViewModel.IRParam_RawImpedanceClampNew);
|
|
inputRangeParameters.MaxFlowRate = UInt16.Parse(windowViewModel.IRParam_MaxFlowRateNew);
|
|
inputRangeParameters.MaxFlowRateAlarmCount = Byte.Parse(windowViewModel.IRParam_MaxFlowRateAlarmCountNew);
|
|
inputRangeParameters.FlowRateStdDevInvSlope = Byte.Parse(windowViewModel.IRParam_FlowRateStdDevInvSlopeNew);
|
|
na2wParamList.Add(inputRangeParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("LowFlowParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.LFParam_EntryRateNew.Length != 0)
|
|
&& (windowViewModel.LFParam_EntryTimeNew.Length != 0)
|
|
&& (windowViewModel.LFParam_ExitRateNew.Length != 0)
|
|
&& (windowViewModel.LFParam_ExitTimeNew.Length != 0)
|
|
&& (windowViewModel.LFParam_LowPowerDelay_minNew.Length != 0)
|
|
)
|
|
{
|
|
LowFlowParameters lowFlowParameters =
|
|
new LowFlowParameters();
|
|
lowFlowParameters.EntryRate = UInt16.Parse(windowViewModel.LFParam_EntryRateNew);
|
|
lowFlowParameters.EntryTime = UInt16.Parse(windowViewModel.LFParam_EntryTimeNew);
|
|
lowFlowParameters.ExitRate = UInt16.Parse(windowViewModel.LFParam_ExitRateNew);
|
|
lowFlowParameters.ExitTime = UInt16.Parse(windowViewModel.LFParam_ExitTimeNew);
|
|
lowFlowParameters.LowPowerDelay_min = Byte.Parse(windowViewModel.LFParam_LowPowerDelay_minNew);
|
|
na2wParamList.Add(lowFlowParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("ImpedanceDriveParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.IDParam_DriveStrengthNew.Length != 0)
|
|
)
|
|
{
|
|
ImpedanceDriveParameters impedanceDriveParameters =
|
|
new ImpedanceDriveParameters();
|
|
impedanceDriveParameters.DriveStrength = Byte.Parse(windowViewModel.IDParam_DriveStrengthNew);
|
|
na2wParamList.Add(impedanceDriveParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("CalibrationFactor"))
|
|
{
|
|
if (
|
|
(windowViewModel.CalibrationFactorNew.Length != 0)
|
|
)
|
|
{
|
|
CalibrationFactor calibrationFactor =
|
|
new CalibrationFactor();
|
|
calibrationFactor.Setting = UInt16.Parse(windowViewModel.CalibrationFactorNew);
|
|
na2wParamList.Add(calibrationFactor);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("ZeroFlowOffsetParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.ZFParam_ZeroFlowOffsetNew.Length != 0)
|
|
&& (windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew.Length != 0)
|
|
)
|
|
{
|
|
ZeroFlowOffsetParameters zeroFlowOffsetParameters =
|
|
new ZeroFlowOffsetParameters();
|
|
zeroFlowOffsetParameters.ZeroFlowOffset = UInt16.Parse(windowViewModel.ZFParam_ZeroFlowOffsetNew);
|
|
zeroFlowOffsetParameters.ZeroFlowOffsetThreshold = UInt16.Parse(windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew);
|
|
na2wParamList.Add(zeroFlowOffsetParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("MeterSize"))
|
|
{
|
|
MeterSize meterSize =
|
|
new MeterSize();
|
|
meterSize.Size = windowViewModel.SterlingMeterSizeNew;
|
|
na2wParamList.Add(meterSize);
|
|
}
|
|
|
|
if (tag.Equals("TargetFieldParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.TFParam_NormalPowerTargetFieldNew.Length != 0)
|
|
&& (windowViewModel.TFParam_LowPowerTargetFieldNew.Length != 0)
|
|
&& (windowViewModel.TFParam_HighPowerTargetFieldNew.Length != 0)
|
|
)
|
|
{
|
|
TargetFieldParameters targetFieldParameters =
|
|
new TargetFieldParameters();
|
|
targetFieldParameters.NormalPowerTargetField = UInt16.Parse(windowViewModel.TFParam_NormalPowerTargetFieldNew);
|
|
targetFieldParameters.LowPowerTargetField = UInt16.Parse(windowViewModel.TFParam_LowPowerTargetFieldNew);
|
|
targetFieldParameters.HighPowerTargetField = UInt16.Parse(windowViewModel.TFParam_HighPowerTargetFieldNew);
|
|
na2wParamList.Add(targetFieldParameters);
|
|
}
|
|
}
|
|
|
|
if (tag.Equals("SpreadSpectrumParameters"))
|
|
{
|
|
if (
|
|
(windowViewModel.SSParam_DisableSpreadSpectrumNew.Length != 0)
|
|
&& (windowViewModel.SSParam_AlwaysUseFullRateBagsNew.Length != 0)
|
|
&& (windowViewModel.SSParam_PowerUpNew.Length != 0)
|
|
&& (windowViewModel.SSParam_HighNoiseNew.Length != 0)
|
|
&& (windowViewModel.SSParam_EmptyPipeNew.Length != 0)
|
|
&& (windowViewModel.SSParam_BadAdcNew.Length != 0)
|
|
&& (windowViewModel.SSParam_InitLearningCompleteCountNew.Length != 0)
|
|
&& (windowViewModel.SSParam_MinOffsetLearningSampleCountNew.Length != 0)
|
|
&& (windowViewModel.SSParam_AdcShiftUpdateIntervalNew.Length != 0)
|
|
&& (windowViewModel.SSParam_MaxPreviousAdcAgeNew.Length != 0)
|
|
&& (windowViewModel.SSParam_AdcOffsetLearningGuardNew.Length != 0)
|
|
&& (windowViewModel.SSParam_DisplacementCorrectionCountNew.Length != 0)
|
|
)
|
|
{
|
|
SpreadSpectrumParameters spreadSpectrumParameters =
|
|
new SpreadSpectrumParameters();
|
|
spreadSpectrumParameters.DisableSpreadSpectrum = Boolean.Parse(windowViewModel.SSParam_DisableSpreadSpectrumNew);
|
|
spreadSpectrumParameters.AlwaysUseFullRateBags = Boolean.Parse(windowViewModel.SSParam_AlwaysUseFullRateBagsNew);
|
|
spreadSpectrumParameters.PowerUp = Byte.Parse(windowViewModel.SSParam_PowerUpNew);
|
|
spreadSpectrumParameters.HighNoise = Byte.Parse(windowViewModel.SSParam_HighNoiseNew);
|
|
spreadSpectrumParameters.EmptyPipe = Byte.Parse(windowViewModel.SSParam_EmptyPipeNew);
|
|
spreadSpectrumParameters.BadAdc = Byte.Parse(windowViewModel.SSParam_BadAdcNew);
|
|
spreadSpectrumParameters.InitLearningCompleteCount = UInt16.Parse(windowViewModel.SSParam_InitLearningCompleteCountNew);
|
|
spreadSpectrumParameters.MinOffsetLearningSampleCount = UInt16.Parse(windowViewModel.SSParam_MinOffsetLearningSampleCountNew);
|
|
spreadSpectrumParameters.AdcShiftUpdateInterval = Byte.Parse(windowViewModel.SSParam_AdcShiftUpdateIntervalNew);
|
|
spreadSpectrumParameters.MaxPreviousAdcAge = Byte.Parse(windowViewModel.SSParam_MaxPreviousAdcAgeNew);
|
|
spreadSpectrumParameters.AdcOffsetLearningGuard = UInt16.Parse(windowViewModel.SSParam_AdcOffsetLearningGuardNew);
|
|
spreadSpectrumParameters.DisplacementCorrectionCount = Byte.Parse(windowViewModel.SSParam_DisplacementCorrectionCountNew);
|
|
na2wParamList.Add(spreadSpectrumParameters);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (na2wParamList.Count != 0)
|
|
{
|
|
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
|
|
parameterWriteCommand.TagMap = (TagMap)5;
|
|
|
|
SendNa2wSerial(parameterWriteCommand, false);
|
|
}
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
if (tagReadList.Count != 0)
|
|
{
|
|
ParameterReadCommand parameterReadCommand = new ParameterReadCommand((TagMap)5, tagReadList);
|
|
SendNa2wSerial(parameterReadCommand, false);
|
|
}
|
|
}
|
|
|
|
public void SetOpticalEnableCommand(string command)
|
|
{
|
|
bool isValidAction = false;
|
|
OpticalDataMode opticalDataModeSet = new OpticalDataMode();
|
|
|
|
if (command.Equals("Enable"))
|
|
{
|
|
opticalDataModeSet.Mode = OpticalDataMode.Enable;
|
|
isValidAction = true;
|
|
}
|
|
else if (command.Equals("Disable"))
|
|
{
|
|
opticalDataModeSet.Mode = OpticalDataMode.Disable;
|
|
isValidAction = true;
|
|
}
|
|
|
|
if (isValidAction)
|
|
{
|
|
// Send command to disable/enable Optical Data.
|
|
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(opticalDataModeSet);
|
|
SendNa2wSerial(parameterWriteCommand, false);
|
|
}
|
|
}
|
|
|
|
public void SessionCommand(string command)
|
|
{
|
|
if (command.Equals("Open"))
|
|
{
|
|
CommDeviceSessionOpen commDeviceSessionOpen = new CommDeviceSessionOpen();
|
|
commDeviceSessionOpen.HostParsed = "GlobalIPerlUtility";
|
|
SendNa2wSerial(commDeviceSessionOpen, false);
|
|
}
|
|
else if (command.Equals("Close"))
|
|
{
|
|
CommDeviceSessionClose commDeviceSessionClose = new CommDeviceSessionClose();
|
|
commDeviceSessionClose.SessionID = sessionId;
|
|
SendNa2wSerial(commDeviceSessionClose, false);
|
|
}
|
|
}
|
|
|
|
public void FileCommand(string command)
|
|
{
|
|
String[] cmdArgs = command.Split(new char[] { ' ' }, 2);
|
|
|
|
if (cmdArgs[0].Equals("ExportConfiguration"))
|
|
{
|
|
Session session = new Session();
|
|
session.Save(cmdArgs[1]);
|
|
}
|
|
else if (cmdArgs[0].Equals("ImportConfiguration"))
|
|
{
|
|
Session session = new Session();
|
|
session.Load(cmdArgs[1]);
|
|
}
|
|
else if (cmdArgs[0].Equals("ReadAll"))
|
|
{
|
|
ReadAllTags();
|
|
}
|
|
else if (cmdArgs[0].Equals("SaveTags"))
|
|
{
|
|
String fileName = TagsToCsv(null);
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " : Tags saved to " + fileName + "\n");
|
|
}
|
|
else if (cmdArgs[0].Equals("Diagnostics"))
|
|
{
|
|
string[] files = cmdArgs[1].Split(new char[] { ',' });
|
|
string mapFile = string.Empty;
|
|
string outputFile = string.Empty;
|
|
if (files.Length > 0)
|
|
{
|
|
outputFile = files[0];
|
|
if (files.Length > 1)
|
|
{
|
|
mapFile = files[1];
|
|
}
|
|
}
|
|
SaveDiagnostics(outputFile, mapFile);
|
|
}
|
|
}
|
|
|
|
public void CopyCommand(string command)
|
|
{
|
|
if (command.Length != 0)
|
|
{
|
|
string[] commands = command.Split(',');
|
|
|
|
for (int i = 0; i < commands.Length; i++)
|
|
{
|
|
string commandIndex = commands[i];
|
|
|
|
if (commandIndex.Equals("RadioConfiguration"))
|
|
{
|
|
windowViewModel.TcxoCorrectionNew = windowViewModel.TcxoCorrection;
|
|
windowViewModel.RfPowerLevelNew = windowViewModel.RfPowerLevel.Split(' ')[0];
|
|
}
|
|
else if (commandIndex.Equals("FactoryId"))
|
|
{
|
|
windowViewModel.FactoryIdNew = windowViewModel.FactoryId;
|
|
}
|
|
else if (commandIndex.Equals("CustomerId"))
|
|
{
|
|
windowViewModel.CustomerIdNew = windowViewModel.CustomerId;
|
|
}
|
|
else if (commandIndex.Equals("BuildInfo"))
|
|
{
|
|
windowViewModel.BuildInfoNew = windowViewModel.BuildInfo;
|
|
}
|
|
else if (commandIndex.Equals("ManufactureDate"))
|
|
{
|
|
UInt32.TryParse(windowViewModel.ManufactureDate, out UInt32 manufactureDate);
|
|
windowViewModel.ManufactureDateNew = manufactureDate;
|
|
}
|
|
else if (commandIndex.Equals("MeterSize"))
|
|
{
|
|
MeterSizeComboBoxItem comboBoxItem = windowViewModel.MeterSizeCollection.Where(x => x.Name == windowViewModel.SterlingMeterSize).FirstOrDefault();
|
|
windowViewModel.SterlingMeterSizeNew = (null != comboBoxItem ? comboBoxItem.Value : (byte)0);
|
|
}
|
|
else if (commandIndex.Equals("DisplayTimeout"))
|
|
{
|
|
windowViewModel.DisplayTimeoutNew = windowViewModel.DisplayTimeout;
|
|
}
|
|
else if (commandIndex.Equals("ZeroFlowOffsetParameters"))
|
|
{
|
|
windowViewModel.ZFParam_ZeroFlowOffsetNew = windowViewModel.ZFParam_ZeroFlowOffset;
|
|
windowViewModel.ZFParam_ZeroFlowOffsetThresholdNew = windowViewModel.ZFParam_ZeroFlowOffsetThreshold;
|
|
}
|
|
else if (commandIndex.Equals("EmptyPipeParameters"))
|
|
{
|
|
windowViewModel.EPParam_ImpedanceThresholdNew = windowViewModel.EPParam_ImpedanceThreshold;
|
|
windowViewModel.EPParam_EmptyTimeThresholdNew = windowViewModel.EPParam_EmptyTimeThreshold;
|
|
windowViewModel.EPParam_HydrationDurationNew = windowViewModel.EPParam_HydrationDuration;
|
|
}
|
|
else if (commandIndex.Equals("InputRangeParameters"))
|
|
{
|
|
windowViewModel.IRParam_AdcRailingHighThresholdNew = windowViewModel.IRParam_AdcRailingHighThreshold;
|
|
windowViewModel.IRParam_AdcRailingLowThresholdNew = windowViewModel.IRParam_AdcRailingLowThreshold;
|
|
windowViewModel.IRParam_MaxAdcThresholdNew = windowViewModel.IRParam_MaxAdcThreshold;
|
|
windowViewModel.IRParam_MaxElectrodeDeltaNew = windowViewModel.IRParam_MaxElectrodeDelta;
|
|
windowViewModel.IRParam_EmfAlarmHoldoffHoursNew = windowViewModel.IRParam_EmfAlarmHoldoffHours;
|
|
windowViewModel.IRParam_AdcNoiseThresholdNew = windowViewModel.IRParam_AdcNoiseThreshold;
|
|
windowViewModel.IRParam_RawImpedanceClampNew = windowViewModel.IRParam_RawImpedanceClamp;
|
|
windowViewModel.IRParam_MaxFlowRateNew = windowViewModel.IRParam_MaxFlowRate;
|
|
windowViewModel.IRParam_MaxFlowRateAlarmCountNew = windowViewModel.IRParam_MaxFlowRateAlarmCount;
|
|
windowViewModel.IRParam_FlowRateStdDevInvSlopeNew = windowViewModel.IRParam_FlowRateStdDevInvSlope;
|
|
}
|
|
else if (commandIndex.Equals("LowFlowParameters"))
|
|
{
|
|
windowViewModel.LFParam_EntryRateNew = windowViewModel.LFParam_EntryRate;
|
|
windowViewModel.LFParam_EntryTimeNew = windowViewModel.LFParam_EntryTime;
|
|
windowViewModel.LFParam_ExitRateNew = windowViewModel.LFParam_ExitRate;
|
|
windowViewModel.LFParam_ExitTimeNew = windowViewModel.LFParam_ExitTime;
|
|
windowViewModel.LFParam_LowPowerDelay_minNew = windowViewModel.LFParam_LowPowerDelay_min;
|
|
}
|
|
else if (commandIndex.Equals("ImpedanceDriveParameters"))
|
|
{
|
|
windowViewModel.IDParam_DriveStrengthNew = windowViewModel.IDParam_DriveStrength;
|
|
}
|
|
else if (commandIndex.Equals("MagneticFieldDriveParameters"))
|
|
{
|
|
windowViewModel.MFDParam_DriveTimeNew = windowViewModel.MFDParam_DriveTime;
|
|
windowViewModel.MFDParam_FieldFitA0New = windowViewModel.MFDParam_FieldFitA0;
|
|
windowViewModel.MFDParam_FieldFitA1New = windowViewModel.MFDParam_FieldFitA1;
|
|
windowViewModel.MFDParam_FieldDriveStepMagnitudeNew = windowViewModel.MFDParam_FieldDriveStepMagnitude;
|
|
windowViewModel.MFDParam_FieldControlHysteresis_mGNew = windowViewModel.MFDParam_FieldControlHysteresis_mG;
|
|
}
|
|
else if (commandIndex.Equals("MagneticTamperParameters"))
|
|
{
|
|
windowViewModel.MTParam_MaxPercentErrorNew = windowViewModel.MTParam_MaxPercentError;
|
|
windowViewModel.MTParam_DetectionCountsNew = windowViewModel.MTParam_DetectionCounts;
|
|
windowViewModel.MTParam_PidSettlingTimeNew = windowViewModel.MTParam_PidSettlingTime;
|
|
windowViewModel.MTParam_DriveLowNew = windowViewModel.MTParam_DriveLow;
|
|
windowViewModel.MTParam_DriveHighNew = windowViewModel.MTParam_DriveHigh;
|
|
}
|
|
else if (commandIndex.Equals("ReverseVolumeBufferParameters"))
|
|
{
|
|
windowViewModel.RVBParam_Threshold_qmlNew = windowViewModel.RVBParam_Threshold_qml;
|
|
windowViewModel.RVBParam_Leak_qml_sNew = windowViewModel.RVBParam_Leak_qml_s;
|
|
}
|
|
else if (commandIndex.Equals("TargetFieldParameters"))
|
|
{
|
|
windowViewModel.TFParam_NormalPowerTargetFieldNew = windowViewModel.TFParam_NormalPowerTargetField;
|
|
windowViewModel.TFParam_LowPowerTargetFieldNew = windowViewModel.TFParam_LowPowerTargetField;
|
|
windowViewModel.TFParam_HighPowerTargetFieldNew = windowViewModel.TFParam_HighPowerTargetField;
|
|
}
|
|
else if (commandIndex.Equals("SpreadSpectrumParameters"))
|
|
{
|
|
windowViewModel.SSParam_DisableSpreadSpectrumNew = windowViewModel.SSParam_DisableSpreadSpectrum;
|
|
windowViewModel.SSParam_AlwaysUseFullRateBagsNew = windowViewModel.SSParam_AlwaysUseFullRateBags;
|
|
windowViewModel.SSParam_PowerUpNew = windowViewModel.SSParam_PowerUp;
|
|
windowViewModel.SSParam_HighNoiseNew = windowViewModel.SSParam_HighNoise;
|
|
windowViewModel.SSParam_EmptyPipeNew = windowViewModel.SSParam_EmptyPipe;
|
|
windowViewModel.SSParam_BadAdcNew = windowViewModel.SSParam_BadAdc;
|
|
windowViewModel.SSParam_InitLearningCompleteCountNew = windowViewModel.SSParam_InitLearningCompleteCount;
|
|
windowViewModel.SSParam_MinOffsetLearningSampleCountNew = windowViewModel.SSParam_MinOffsetLearningSampleCount;
|
|
windowViewModel.SSParam_AdcShiftUpdateIntervalNew = windowViewModel.SSParam_AdcShiftUpdateInterval;
|
|
windowViewModel.SSParam_MaxPreviousAdcAgeNew = windowViewModel.SSParam_MaxPreviousAdcAge;
|
|
windowViewModel.SSParam_AdcOffsetLearningGuardNew = windowViewModel.SSParam_AdcOffsetLearningGuard;
|
|
windowViewModel.SSParam_DisplacementCorrectionCountNew = windowViewModel.SSParam_DisplacementCorrectionCount;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void FactoryResetCommand()
|
|
{
|
|
UInt32 resetFlags = 0;
|
|
|
|
if (windowViewModel.FactoryResetId) resetFlags |= 0x0001;
|
|
if (windowViewModel.FactoryResetCalibration) resetFlags |= 0x0002;
|
|
//if (windowViewModel.FactoryResetConfiguration) resetFlags |= 0x0008;
|
|
if (windowViewModel.FactoryResetEventLog) resetFlags |= 0x0010;
|
|
if (windowViewModel.FactoryResetStatistics) resetFlags |= 0x0004;
|
|
if (windowViewModel.FactoryResetProductTime) resetFlags |= 0x0008;
|
|
|
|
FactoryTestCommand_FactoryReset factTestFactoryReset = new FactoryTestCommand_FactoryReset();
|
|
|
|
factTestFactoryReset.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
factTestFactoryReset.ResetFlags = resetFlags;
|
|
factTestFactoryReset.ResetDelay = 1000;
|
|
|
|
SendNa2wSerial(factTestFactoryReset, false);
|
|
}
|
|
|
|
public void TestCommand(string command)
|
|
{
|
|
if (command.Equals("EngineeringCw"))
|
|
{
|
|
UInt32 frequency;
|
|
Byte duration;
|
|
UInt16 transceiverPower;
|
|
|
|
if (
|
|
UInt32.TryParse(windowViewModel.TxEng_Frequency, out frequency)
|
|
&& Byte.TryParse(windowViewModel.TxEng_Duration, out duration)
|
|
&& UInt16.TryParse(windowViewModel.TxEng_TransceiverPower, out transceiverPower)
|
|
)
|
|
{
|
|
FactoryTestCommand_EngineeringCw factTestCmdEngCw = new FactoryTestCommand_EngineeringCw();
|
|
|
|
factTestCmdEngCw.Frequency = frequency;
|
|
factTestCmdEngCw.Duration = duration;
|
|
factTestCmdEngCw.TransceiverPower = transceiverPower;
|
|
factTestCmdEngCw.FemPower = 0; // Ignored
|
|
factTestCmdEngCw.AttenuatorPower = 0; // Ignored
|
|
|
|
SendNa2wSerial(factTestCmdEngCw, false);
|
|
}
|
|
}
|
|
else if (command.Equals("EngineeringFcc"))
|
|
{
|
|
UInt32 frequency;
|
|
Byte duration;
|
|
UInt16 transceiverPower;
|
|
|
|
if (
|
|
UInt32.TryParse(windowViewModel.TxEng_Frequency, out frequency)
|
|
&& Byte.TryParse(windowViewModel.TxEng_Duration, out duration)
|
|
&& UInt16.TryParse(windowViewModel.TxEng_TransceiverPower, out transceiverPower)
|
|
)
|
|
{
|
|
FactoryTestCommand_EngineeringFcc factTestCmdEngFcc = new FactoryTestCommand_EngineeringFcc();
|
|
|
|
factTestCmdEngFcc.Modulation = 10; // SensusRF 100k
|
|
factTestCmdEngFcc.Frequency = frequency;
|
|
factTestCmdEngFcc.Duration = duration;
|
|
factTestCmdEngFcc.TransceiverPower = transceiverPower;
|
|
factTestCmdEngFcc.FemPower = 0; // Ignored
|
|
factTestCmdEngFcc.AttenuatorPower = 0; // Ignored
|
|
|
|
SendNa2wSerial(factTestCmdEngFcc, false);
|
|
}
|
|
}
|
|
else if (command.Equals("RegulatoryCw"))
|
|
{
|
|
UInt32 frequency;
|
|
Byte duration;
|
|
|
|
if (
|
|
UInt32.TryParse(windowViewModel.Tx_Frequency, out frequency)
|
|
&& Byte.TryParse(windowViewModel.Tx_Duration, out duration)
|
|
)
|
|
{
|
|
FactoryTestCommand_RegulatoryCw factTestCmdRegCw = new FactoryTestCommand_RegulatoryCw();
|
|
|
|
factTestCmdRegCw.Frequency = frequency;
|
|
factTestCmdRegCw.Duration = duration;
|
|
factTestCmdRegCw.PowerLevel = Int16.MaxValue; // Ignored
|
|
|
|
SendNa2wSerial(factTestCmdRegCw, false);
|
|
}
|
|
}
|
|
else if (command.Equals("RegulatoryFcc"))
|
|
{
|
|
UInt32 frequency;
|
|
Byte duration;
|
|
|
|
if (
|
|
UInt32.TryParse(windowViewModel.Tx_Frequency, out frequency)
|
|
&& Byte.TryParse(windowViewModel.Tx_Duration, out duration)
|
|
)
|
|
{
|
|
FactoryTestCommand_RegulatoryFcc factTestCmdRegFcc = new FactoryTestCommand_RegulatoryFcc();
|
|
|
|
factTestCmdRegFcc.Modulation = 10; // SensusRF 100k
|
|
factTestCmdRegFcc.Frequency = frequency;
|
|
factTestCmdRegFcc.Duration = duration;
|
|
factTestCmdRegFcc.PowerLevel = Int16.MaxValue; // Ignored
|
|
|
|
SendNa2wSerial(factTestCmdRegFcc, false);
|
|
}
|
|
}
|
|
else if (command.Equals("FrequencyCount"))
|
|
{
|
|
FactoryTestCommand_FrequencyCount factTestFrequencyCount = new FactoryTestCommand_FrequencyCount();
|
|
factTestFrequencyCount.Reserved = 0;
|
|
|
|
SendNa2wSerial(factTestFrequencyCount, false);
|
|
}
|
|
else if (command.Equals("LockDebugInterface"))
|
|
{
|
|
FactoryTestCommand_LockDebugInterface lockDebugInterface = new FactoryTestCommand_LockDebugInterface();
|
|
|
|
SendNa2wSerial(lockDebugInterface, false);
|
|
}
|
|
}
|
|
|
|
public partial class Ping_Normal : Sensus.Protocols.FlexNet.Ping
|
|
{
|
|
public Ping_Normal()
|
|
: base()
|
|
{
|
|
PingType = PingType.Normal;
|
|
Init();
|
|
}
|
|
|
|
partial void Init();
|
|
|
|
public static new Ping_Normal Parse(byte[] buffer, uint offset)
|
|
{
|
|
return Command.Parse<Ping_Normal>(buffer, offset, CommandLength);
|
|
}
|
|
}
|
|
|
|
public void SendPacket(String type)
|
|
{
|
|
if (type.Equals("Radio"))
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = 0x02; // Activity BUP // KGI is this correct?
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
else if (type.Equals("ActivityBup"))
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = 0x02; // Activity BUP
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
#if false // this is an example of sending the set tfx params command as a radio frame
|
|
else if (type.Equals("StartPeriodicReadingTransmit"))
|
|
{
|
|
byte[] payload = new byte[] {
|
|
0xAC, 0xC5, // SyncWord
|
|
0x1A, // FlexType 10, FlexInfo (1 = downlink)
|
|
0x00, 0x00, 0x00, 0x00, // TFX ID
|
|
0x12, 0xC0, // Length (18 bytes) & FEC Type (3/4 K=4)
|
|
// MAC Header
|
|
0x00, 0x40, // Downlink Flags (0 = SessionId) 1(4:6)(4 = Source)(Register)
|
|
// MAC Payload
|
|
// MAC Payload Header
|
|
0x80, 0x03, // Channel (:4), SignaturePresent (:1), Reserved (:2), Length (:9 - 7 = 1+12+1/2)
|
|
0xF3, // CmdMsgCode = 0xF3 - Set TFXv2 Parameters
|
|
// Set TFXv2 Parameters
|
|
0x00, // Version (:4), Reserved (:4)
|
|
0x2f, // Device Type (DT47)
|
|
0b00111010, // Time Changed (:1), MTR Changed (:1), History Size Changed (:1), TFXv2 State Changed (:1), Active State Changed (:1), Meter Sample Rate Changed (:1), History Scale Changed (:1), Reset History (:1)
|
|
0x00, 0x00, 0x00, 0x00, // Epoch Time
|
|
0x00, // History Size
|
|
(byte)((windowViewModel.MeterTransmitRateNew) | (1<<3) | (1<<5)), // MTR (:3)(), TFXv2 State (:2)(1=active), Active State (:1)(1), Meter Type Changed (:1), Encoder Digits Changed (:1)
|
|
0x00, // Meter Units Changed (:1), Meter Sample Rate (:3)(0=5min), Meter Type (:4)
|
|
0x00, // Encoder Digits (:3), Reading Resolution Changed (:1), Reading Resolution (:4)
|
|
0x00, // History Scale (:2), Meter Units (:3), Reserved (:3)
|
|
0x00, // padding
|
|
0x00, 0x00, 0x00, 0x00 // CRC
|
|
};
|
|
|
|
UInt32 txAddr;
|
|
|
|
if (!Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out txAddr))
|
|
{
|
|
txAddr = 0x123456;
|
|
}
|
|
|
|
/* Update the DUT address in the payload */
|
|
payload.Write<UInt32>(txAddr, (uint)(3) * 8, 32);
|
|
|
|
/* Calculate and update the CRC */
|
|
var crc = ~CRC32.Calculate(payload, 3, payload.Length - 7);
|
|
payload.Write<UInt32>(crc, (uint)(payload.Length - 4) * 8, 32);
|
|
Frame frame = new Frame(payload);
|
|
|
|
SendNa2wSerial(frame, false);
|
|
}
|
|
#endif
|
|
else if (type.Equals("StartPeriodicReadingTransmit"))
|
|
{
|
|
byte[] txPeriodicReading = new byte[] {
|
|
0x01, // Active
|
|
(byte)(windowViewModel.MeterTransmitRateNew), // MTR
|
|
};
|
|
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxPeriodicReading;
|
|
engineeringTestCommand.Payload = new Frame(txPeriodicReading);
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
#if false // this is an example of sending the set tfx params command as a radio frame
|
|
else if (type.Equals("StopPeriodicReadingTransmit"))
|
|
{
|
|
byte[] payload = new byte[] {
|
|
0xAC, 0xC5, // SyncWord
|
|
0x1A, // FlexType 10, FlexInfo (1 = downlink)
|
|
0x00, 0x00, 0x00, 0x00, // TFX ID
|
|
0x12, 0xC0, // Length (18 bytes) & FEC Type (3/4 K=4)
|
|
// MAC Header
|
|
0x00, 0x40, // Downlink Flags (0 = SessionId) 1(4:6)(4 = Source)(Register)
|
|
// MAC Payload
|
|
// MAC Payload Header
|
|
0x80, 0x03, // Channel (:4), SignaturePresent (:1), Reserved (:2), Length (:9 - 7 = 1+12+1/2)
|
|
0xF3, // CmdMsgCode = 0xF3 - Set TFXv2 Parameters
|
|
// Set TFXv2 Parameters
|
|
0x00, // Version (:4), Reserved (:4)
|
|
0x2f, // Device Type (DT47)
|
|
0b00111010, // Time Changed (:1), MTR Changed (:1), History Size Changed (:1), TFXv2 State Changed (:1), Active State Changed (:1), Meter Sample Rate Changed (:1), History Scale Changed (:1), Reset History (:1)
|
|
0x00, 0x00, 0x00, 0x00, // Epoch Time
|
|
0x00, // History Size
|
|
(0) | (0<<3) | (0<<5), // MTR (:3)(6=12seconds), TFXv2 State (:2)(1=active), Active State (:1)(1), Meter Type Changed (:1), Encoder Digits Changed (:1)
|
|
0x00, // Meter Units Changed (:1), Meter Sample Rate (:3)(0=5min), Meter Type (:4)
|
|
0x00, // Encoder Digits (:3), Reading Resolution Changed (:1), Reading Resolution (:4)
|
|
0x00, // History Scale (:2), Meter Units (:3), Reserved (:3)
|
|
0x00, // padding
|
|
0x00, 0x00, 0x00, 0x00 // CRC
|
|
};
|
|
|
|
UInt32 txAddr;
|
|
|
|
if (!Conversion.TryParseHexOrDecString(windowViewModel.DeviceIdNew, out txAddr))
|
|
{
|
|
txAddr = 0x123456;
|
|
}
|
|
|
|
/* Update the DUT address in the payload */
|
|
payload.Write<UInt32>(txAddr, (uint)(3) * 8, 32);
|
|
|
|
/* Calculate and update the CRC */
|
|
var crc = ~CRC32.Calculate(payload, 3, payload.Length - 7);
|
|
payload.Write<UInt32>(crc, (uint)(payload.Length - 4) * 8, 32);
|
|
Frame frame = new Frame(payload);
|
|
|
|
SendNa2wSerial(frame, false);
|
|
}
|
|
#endif
|
|
else if (type.Equals("StopPeriodicReadingTransmit"))
|
|
{
|
|
byte[] txPeriodicReading = new byte[] {
|
|
0x00, // not Active
|
|
0x00, // MTR
|
|
};
|
|
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxPeriodicReading;
|
|
engineeringTestCommand.Payload = new Frame(txPeriodicReading);
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
else if (type.Equals("Na2wSerial"))
|
|
{
|
|
try
|
|
{
|
|
byte[] data = Conversion.HexStringToBytes(windowViewModel.SerialSendData);
|
|
if (data.Length > 0)
|
|
{
|
|
byte code = data[0];
|
|
|
|
uint payloadLength = (uint)(data.Length - 1);
|
|
byte[] payload = new byte[payloadLength];
|
|
Array.Copy(data, 1, payload, 0, payloadLength);
|
|
|
|
SerialCommand serialCommand = new SerialCommand(code, payload);
|
|
serialCommand.Bake();
|
|
SendNa2wSerial(serialCommand, false);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ListenCommand(String type)
|
|
{
|
|
if (type.Equals("RadioOn"))
|
|
{
|
|
Byte modulation;
|
|
UInt32 frequency;
|
|
|
|
if (UInt32.TryParse(windowViewModel.Rx_Frequency, out frequency))
|
|
{
|
|
RadioListenV1 radioListen = new RadioListenV1();
|
|
radioListen.PortId = 0x00;
|
|
radioListen.DataRate = RadioReceiveDataRate._100kbps;
|
|
radioListen.RadioReceiveModulation = (RadioReceiveModulationType)6; // RadioReceiveModulationType._2GFSK_TFX;
|
|
radioListen.Frequency = frequency;
|
|
|
|
if (windowViewModel.Rx_Sensitivity == "Low")
|
|
{
|
|
radioListen.Sensitivity = 0x01;
|
|
}
|
|
|
|
SendNa2wSerial(radioListen, false);
|
|
}
|
|
}
|
|
else if (type.Equals("RadioOff"))
|
|
{
|
|
RadioListenV1 radioListen = new RadioListenV1();
|
|
radioListen.PortId = 0x00;
|
|
radioListen.Frequency = 0x00000; // 0 indicates stop
|
|
radioListen.DataRate = RadioReceiveDataRate._100kbps;
|
|
radioListen.RadioReceiveModulation = (RadioReceiveModulationType)6; // RadioReceiveModulationType._2GFSK_TFX;
|
|
|
|
SendNa2wSerial(radioListen, false);
|
|
}
|
|
else if (type.Equals("RSSI"))
|
|
{
|
|
Byte modulation;
|
|
UInt32 frequency;
|
|
|
|
if (UInt32.TryParse(windowViewModel.Rx_Frequency, out frequency))
|
|
{
|
|
FactoryTestCommand_SampleRfSignal sampleRfSignal = new FactoryTestCommand_SampleRfSignal();
|
|
sampleRfSignal.Samples = 8;
|
|
|
|
sampleRfSignal.DataRate = RadioReceiveDataRate._100kbps;
|
|
sampleRfSignal.Frequency = frequency;
|
|
|
|
if (windowViewModel.Rx_Sensitivity == "Low")
|
|
{
|
|
sampleRfSignal.Sensitivity = 0x01;
|
|
}
|
|
|
|
SendNa2wSerial(sampleRfSignal, false);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void ResetCommand(String type)
|
|
{
|
|
if (type.Equals("SW"))
|
|
{
|
|
ResetSoftware resetSoftware = new ResetSoftware();
|
|
resetSoftware.ResetDelay = 1; // 1 ms
|
|
SendNa2wSerial(resetSoftware, false);
|
|
}
|
|
else if (type.Equals("WD"))
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.WdReset;
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
}
|
|
public void PowerDomainCommand(string param)
|
|
{
|
|
BitArray powerDomainComamndBits = new BitArray(4 * 8); // four bytes of payload
|
|
byte[] powerDomainComamndPayload = new byte[4];
|
|
|
|
if (windowViewModel.PowerDomainEnable_ExternalFlash)
|
|
{
|
|
powerDomainComamndBits.Set(0x00, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_RadioTx)
|
|
{
|
|
powerDomainComamndBits.Set(0x02, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_RadioRx)
|
|
{
|
|
powerDomainComamndBits.Set(0x03, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_Nfc)
|
|
{
|
|
powerDomainComamndBits.Set(0x0A, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_Rail)
|
|
{
|
|
powerDomainComamndBits.Set(0x16, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_MetrologyAsic)
|
|
{
|
|
powerDomainComamndBits.Set(0x1C, true);
|
|
}
|
|
if (windowViewModel.PowerDomainEnable_OpticalLed)
|
|
{
|
|
powerDomainComamndBits.Set(0x1D, true);
|
|
}
|
|
|
|
if (param == "Enable")
|
|
{
|
|
powerDomainComamndBits.Set(0x1F, true);
|
|
}
|
|
else if (param == "Disable")
|
|
{
|
|
powerDomainComamndBits.Set(0x1F, false);
|
|
}
|
|
|
|
// Convert to byte array with little endianness.
|
|
bool bitVal;
|
|
uint writeIdx;
|
|
int byteIdx, bitIdx;
|
|
for (byteIdx = 0; byteIdx < 4; byteIdx++)
|
|
{
|
|
for (bitIdx = 0; bitIdx < 8; bitIdx++)
|
|
{
|
|
bitVal = powerDomainComamndBits[byteIdx * 8 + bitIdx];
|
|
writeIdx = (uint)(byteIdx * 8) + (uint)(bitIdx);
|
|
powerDomainComamndPayload.Write(bitVal, writeIdx, 1);
|
|
}
|
|
}
|
|
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.PowerSwitch;
|
|
engineeringTestCommand.Payload = new Frame(powerDomainComamndPayload);
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
public void ComaSleepCommand()
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.ComaSleep;
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
public void ExternalFlashTest(String param)
|
|
{
|
|
byte[] extFlashTestComamndPayload = new byte[7];
|
|
byte startAddrVal = 0;
|
|
byte stopAddrVal = 0;
|
|
UInt16 cyclesVal = 0;
|
|
UInt16 failuresVal = 0;
|
|
|
|
if (param == "Start")
|
|
{
|
|
if (Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashStart, out startAddrVal)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashStop, out stopAddrVal)
|
|
&& (windowViewModel.ExtFlashTest_InfiniteCycles || Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashCycles, out cyclesVal))
|
|
&& (windowViewModel.ExtFlashTest_InfiniteFailures || Conversion.TryParseHexOrDecString(windowViewModel.ExtFlashFailures, out failuresVal))
|
|
)
|
|
{
|
|
extFlashTestComamndPayload[0] = startAddrVal;
|
|
extFlashTestComamndPayload[1] = stopAddrVal;
|
|
if (windowViewModel.ExtFlashTest_InfiniteCycles == false)
|
|
{
|
|
extFlashTestComamndPayload[2] = (byte)(cyclesVal & 0xFF);
|
|
extFlashTestComamndPayload[3] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
else
|
|
{
|
|
cyclesVal = 0xFFFF;
|
|
extFlashTestComamndPayload[2] = (byte)(cyclesVal & 0xFF);
|
|
extFlashTestComamndPayload[3] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
if (windowViewModel.ExtFlashTest_InfiniteFailures == false)
|
|
{
|
|
extFlashTestComamndPayload[4] = (byte)(failuresVal & 0xFF);
|
|
extFlashTestComamndPayload[5] = (byte)((failuresVal >> 8) & 0xFF);
|
|
}
|
|
else
|
|
{
|
|
cyclesVal = 0xFFFF;
|
|
extFlashTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
|
|
extFlashTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Parameter parsing failed, do nothing.
|
|
System.Console.WriteLine("Malformed parameters.\n");
|
|
return;
|
|
}
|
|
|
|
if (windowViewModel.ExtFlashPatternSelectedItem == "0x55")
|
|
{
|
|
extFlashTestComamndPayload[6] = (byte)0x55;
|
|
}
|
|
else if (windowViewModel.ExtFlashPatternSelectedItem == "0xAA")
|
|
{
|
|
extFlashTestComamndPayload[6] = (byte)0xAA;
|
|
}
|
|
}
|
|
else if (param == "Stop")
|
|
{
|
|
// Do nothing. Cycle count of 0 will cancel the test.
|
|
}
|
|
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.ExternalFlashTest;
|
|
engineeringTestCommand.Payload = new Frame(extFlashTestComamndPayload);
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
public void OpticalDataLedTest(String param)
|
|
{
|
|
byte[] opticalDataLedTestComamndPayload = new byte[1];
|
|
|
|
if (param.Equals("LedOn"))
|
|
{
|
|
opticalDataLedTestComamndPayload[0] = 0x01;
|
|
}
|
|
else if (param.Equals("LedOff"))
|
|
{
|
|
opticalDataLedTestComamndPayload[0] = 0x00;
|
|
}
|
|
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.OpticalLedToggle;
|
|
engineeringTestCommand.Payload = new Frame(opticalDataLedTestComamndPayload);
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
public void NfcEepromTest(String param)
|
|
{
|
|
byte[] nfcEepromTestComamndPayload = new byte[9];
|
|
UInt16 startAddrVal = 0;
|
|
UInt16 stopAddrVal = 0;
|
|
UInt16 cyclesVal = 0;
|
|
UInt16 failuresVal = 0;
|
|
if (param == "Start")
|
|
{
|
|
if (Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromStart, out startAddrVal)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromStop, out stopAddrVal)
|
|
&& (windowViewModel.NfcEepromTest_InfiniteCycles || Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromCycles, out cyclesVal))
|
|
&& (windowViewModel.NfcEepromTest_InfiniteFailures || Conversion.TryParseHexOrDecString(windowViewModel.NfcEepromFailures, out failuresVal))
|
|
)
|
|
{
|
|
nfcEepromTestComamndPayload[0] = (byte)(startAddrVal & 0xFF);
|
|
nfcEepromTestComamndPayload[1] = (byte)((startAddrVal >> 8) & 0xFF);
|
|
nfcEepromTestComamndPayload[2] = (byte)(stopAddrVal & 0xFF);
|
|
nfcEepromTestComamndPayload[3] = (byte)((stopAddrVal >> 8) & 0xFF);
|
|
if (windowViewModel.NfcEepromTest_InfiniteCycles == false)
|
|
{
|
|
nfcEepromTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
|
|
nfcEepromTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
else
|
|
{
|
|
cyclesVal = 0xFFFF;
|
|
nfcEepromTestComamndPayload[4] = (byte)(cyclesVal & 0xFF);
|
|
nfcEepromTestComamndPayload[5] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
if (windowViewModel.NfcEepromTest_InfiniteFailures == false)
|
|
{
|
|
nfcEepromTestComamndPayload[6] = (byte)(failuresVal & 0xFF);
|
|
nfcEepromTestComamndPayload[7] = (byte)((failuresVal >> 8) & 0xFF);
|
|
}
|
|
else
|
|
{
|
|
cyclesVal = 0xFFFF;
|
|
nfcEepromTestComamndPayload[6] = (byte)(cyclesVal & 0xFF);
|
|
nfcEepromTestComamndPayload[7] = (byte)((cyclesVal >> 8) & 0xFF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Parameter parsing failed, do nothing.
|
|
System.Console.WriteLine("Malformed parameters.\n");
|
|
return;
|
|
}
|
|
if (windowViewModel.NfcEepromPatternSelectedItem == "0x55")
|
|
{
|
|
nfcEepromTestComamndPayload[8] = (byte)0x55;
|
|
}
|
|
else if (windowViewModel.NfcEepromPatternSelectedItem == "0xAA")
|
|
{
|
|
nfcEepromTestComamndPayload[8] = (byte)0xAA;
|
|
}
|
|
}
|
|
else if (param == "Stop")
|
|
{
|
|
// Do nothing. Cycle count of 0 will cancel the test.
|
|
}
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.NfcEepromTest;
|
|
engineeringTestCommand.Payload = new Frame(nfcEepromTestComamndPayload);
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
public void RefreshComPortListCommand()
|
|
{
|
|
SetComPortList(GetPortNames());
|
|
}
|
|
|
|
public void ClearCommand(string type)
|
|
{
|
|
if (type.Equals("RadioReceive"))
|
|
{
|
|
windowViewModel.ClearRadioReceived();
|
|
}
|
|
}
|
|
|
|
public void MemoryReadCommand(String type)
|
|
{
|
|
if (type.Equals("Start"))
|
|
{
|
|
UInt32 address;
|
|
UInt16 bytes;
|
|
String memoryType = windowViewModel.MemoryReadTypeSelectedValue;
|
|
|
|
if (
|
|
Conversion.TryParseHexOrDecString(windowViewModel.MemoryReadAddress, out address)
|
|
&& Conversion.TryParseHexOrDecString(windowViewModel.MemoryReadBytes, out bytes)
|
|
)
|
|
{
|
|
MemoryReadCommand memoryReadCommand = new MemoryReadCommand();
|
|
memoryReadCommand.Address = address;
|
|
memoryReadCommand.NumBytes = bytes;
|
|
|
|
if (memoryType.Equals("Serial Flash"))
|
|
{
|
|
memoryReadCommand.Source = 1;
|
|
}
|
|
else if (memoryType.Equals("Processor"))
|
|
{
|
|
memoryReadCommand.Source = 0;
|
|
}
|
|
|
|
SendNa2wSerial(memoryReadCommand, false);
|
|
}
|
|
}
|
|
else if (type.Equals("Stop"))
|
|
{
|
|
}
|
|
}
|
|
|
|
public void EventSendCommand()
|
|
{
|
|
#if false
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.ESAAPPulseOutputModule;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.GenerateEvent;
|
|
|
|
String eventData = windowViewModel.EventSendData.Trim();
|
|
if (eventData.Length > 0)
|
|
{
|
|
if (eventData.Length > 32)
|
|
{
|
|
eventData = eventData.Substring(0, 32);
|
|
}
|
|
eventData += '\0';
|
|
engineeringTestCommand.Payload = new Frame(eventData.ToASCIIBytes());
|
|
}
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
#endif
|
|
}
|
|
|
|
public void ParseCommand(String type)
|
|
{
|
|
if (type.Equals("Frame"))
|
|
{
|
|
try
|
|
{
|
|
byte[] data = Conversion.HexStringToBytes(windowViewModel.FrameParseHexString);
|
|
if (data.Length > 0)
|
|
{
|
|
if (data[0] == 0x1b)
|
|
{
|
|
ISerialMessageFrame message = (ISerialMessageFrame)ClassicSerialMessageFrame.Parse(data, 0);
|
|
windowViewModel.FrameParseText = message.ToString();
|
|
}
|
|
else if (data[0] == 0x6b)
|
|
{
|
|
ISerialMessageFrame message = (ISerialMessageFrame)NA2WSerialFrame.Parse(data, 0, (uint)data.Length);
|
|
windowViewModel.FrameParseText = message.ToString();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.FrameParseText = "";
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
windowViewModel.FrameParseText = "";
|
|
}
|
|
}
|
|
else if (type.Equals("Stats"))
|
|
{
|
|
if (windowViewModel.StatsLogSelectedIndex >= 0)
|
|
{
|
|
// Instantiate the regular expression object.
|
|
Regex r = new Regex(@"\((\d+)\)$", RegexOptions.IgnoreCase);
|
|
|
|
// Match the regular expression pattern against a text string.
|
|
Match m = r.Match(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Id);
|
|
String idMatchString = "";
|
|
|
|
if (m.Success)
|
|
{
|
|
Group g = m.Groups[1];
|
|
CaptureCollection cc = g.Captures;
|
|
Capture c = cc[0];
|
|
idMatchString = c.ToString();
|
|
}
|
|
|
|
byte moduleId = Byte.Parse(idMatchString);
|
|
byte revision = Byte.Parse(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Revision);
|
|
byte[] data = Conversion.HexStringToBytes(windowViewModel.StatsLogCollection[windowViewModel.StatsLogSelectedIndex].Data);
|
|
|
|
windowViewModel.StatsParseText = GlobalIPerlStatistics.Parse((ModuleId)moduleId, revision, data);
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.StatsParseText = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
public void NfcCommand(String type)
|
|
{
|
|
if (type.Equals("Inventory"))
|
|
{
|
|
NfcCommand_InventoryRead nfcCommand = new NfcCommand_InventoryRead();
|
|
SendNa2wSerial(nfcCommand, false);
|
|
}
|
|
else if (type.Equals("NDEF Read"))
|
|
{
|
|
NfcCommand_NdefRead nfcCommand = new NfcCommand_NdefRead();
|
|
SendNa2wSerial(nfcCommand, false);
|
|
}
|
|
}
|
|
|
|
public void LcdCommand(String type)
|
|
{
|
|
bool valid = false;
|
|
UInt16 duration = 0;
|
|
UInt16 period = 0;
|
|
byte width = 0;
|
|
|
|
if (type.Equals("Normal"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.NormalOperation;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("SegmentsOn"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.SegmentsOn;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("SegmentsOff"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.SegmentsOff;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("EvenSegmentsOn"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.EvenSegmentsOn;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("OddSegmentsOn"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.OddSegmentsOn;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("PowerOff"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.DisplayPowerOff;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("TestSequence"))
|
|
{
|
|
FactoryTestCommand_NfcControl nfcControlTestCommand = new FactoryTestCommand_NfcControl();
|
|
nfcControlTestCommand.NfcCommand = (byte)FactoryTestCommand_NfcControl._NfcCommand.TestSequence;
|
|
|
|
SendNa2wSerial(nfcControlTestCommand, false);
|
|
}
|
|
else if (type.Equals("SwitchOpen"))
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)3;
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
else if (type.Equals("SwitchClose"))
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)4;
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
}
|
|
|
|
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload, byte[] key)
|
|
{
|
|
bool encrypted = (key != null);
|
|
|
|
// Sync 04 25
|
|
// Length 3D
|
|
// Type 20 (PAM)
|
|
// Counter 91
|
|
// Address FF C3 87 E9
|
|
// CRC 21 96
|
|
// PAM Code F8
|
|
// PAM Payload 99
|
|
// Enc CRC C4 2B
|
|
// CRC A8 A1
|
|
byte[] srfFrame = new byte[2 + 9 + pamPayload.Length + (encrypted ? 2 : 0) + 2];
|
|
|
|
// Sync
|
|
srfFrame[0] = 0x04;
|
|
srfFrame[1] = 0x25;
|
|
|
|
// Header
|
|
// byte Length
|
|
// byte AppCode - 32 (PAM)
|
|
// byte Counter
|
|
// UInt32 Address
|
|
// UInt16 HeaderCrc
|
|
srfFrame[2] = (byte)(11 + pamPayload.Length + (encrypted ? 2 : 0)); // Header (7) + CRC (2) + PAM Payload + Encryption CRC (2) + Payload CRC (2)
|
|
srfFrame[3] = (byte)Sensus.Protocols.SensusRF.TelegramType.PAM;
|
|
srfFrame[4] = 1; // Counter.AppSequence = 0x01
|
|
srfFrame.Write<UInt32>(srfAddress, (8 * 5), 32, ByteOrder.BigEndian);
|
|
UInt16 headerCRC = CRC16.SIRT.Calculate(srfFrame, 2, 7);
|
|
srfFrame.Write<UInt16>(headerCRC, (8 * 9), 16, ByteOrder.BigEndian);
|
|
|
|
// PAM
|
|
// byte PamPayload
|
|
Array.Copy(pamPayload, 0, srfFrame, 11, pamPayload.Length);
|
|
|
|
byte[] encryptedData;
|
|
int plaintextLength = srfFrame.Length - 2 /* sync */ - 9 /* header and header CRC */ - 2 /* frameCrc */;
|
|
|
|
if (encrypted)
|
|
{
|
|
// UInt16 PayloadCrc (Encrypt CRC)
|
|
UInt16 payloadCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
CRC16.SIRT.Calculate(new byte[] { (byte)((srfAddress >> 16) & 0xFF), (byte)((srfAddress >> 8) & 0xFF), (byte)(srfAddress & 0xFF) })
|
|
),
|
|
srfFrame,
|
|
11,
|
|
plaintextLength - 2
|
|
);
|
|
srfFrame.Write<UInt16>(payloadCRC, (uint)(8 * (11 + plaintextLength - 2)), 16, ByteOrder.BigEndian);
|
|
|
|
// Encrypt
|
|
byte[] plaintextData = new byte[plaintextLength];
|
|
Array.Copy(srfFrame, 11, plaintextData, 0, plaintextLength);
|
|
encryptedData = Sensus.Protocols.SensusRF.TelegramFrame.Encrypt(srfAddress, srfFrame[4], plaintextData, key);
|
|
Array.Copy(encryptedData, 0, srfFrame, 11, plaintextLength);
|
|
}
|
|
else
|
|
{
|
|
encryptedData = new byte[plaintextLength];
|
|
Array.Copy(srfFrame, 11, encryptedData, 0, plaintextLength);
|
|
}
|
|
|
|
// CRC
|
|
UInt16 frameCRC = CRC16.SIRT.Calculate(encryptedData);
|
|
srfFrame.Write<UInt16>(frameCRC, (uint)(8 * (srfFrame.Length - 2)), 16, ByteOrder.BigEndian);
|
|
|
|
return srfFrame;
|
|
}
|
|
|
|
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload, bool encrypt)
|
|
{
|
|
return BuildSensusRFPam(srfAddress, pamPayload, encrypt ? SensusRfKey() : null);
|
|
}
|
|
|
|
public byte[] BuildSensusRFPam(UInt32 srfAddress, byte[] pamPayload)
|
|
{
|
|
return BuildSensusRFPam(srfAddress, pamPayload, true);
|
|
}
|
|
|
|
private byte[] PrependAuthLevel(byte[] payload, String levelName)
|
|
{
|
|
byte[] authPin = new byte[0];
|
|
|
|
if (levelName.Equals("Level 1"))
|
|
{
|
|
if (windowViewModel.SRfPin1SelectedItem.Equals("Default"))
|
|
{
|
|
authPin = new byte[] { 67, 0x01, 0x14, 0x30, 0x68, 0xD0 };
|
|
}
|
|
}
|
|
else if (levelName.Equals("Level 2"))
|
|
{
|
|
authPin = new byte[] { 67, 0x02, 0x14, 0x0E, 0x80, 0x40 };
|
|
}
|
|
else if (levelName.Equals("Level 3"))
|
|
{
|
|
authPin = new byte[] { 67, 0x03, 0x63, 0x93, 0x73, 0x22 };
|
|
}
|
|
|
|
byte[] newPayload = new byte[authPin.Length + payload.Length];
|
|
Array.Copy(authPin, newPayload, authPin.Length);
|
|
Array.Copy(payload, 0, newPayload, authPin.Length, payload.Length);
|
|
|
|
return newPayload;
|
|
}
|
|
|
|
public void SensusRfCommand(String type)
|
|
{
|
|
if (type.Equals("TxBup"))
|
|
{
|
|
if (false)
|
|
{
|
|
EngineeringTestCommand engineeringTestCommand = new EngineeringTestCommand();
|
|
engineeringTestCommand.ProductType = (byte)NA2WProductType.GlobalIPerl;
|
|
engineeringTestCommand.TestCommand = (byte)EngineerTestCommandList.TxBup;
|
|
|
|
SendNa2wSerial(engineeringTestCommand, false);
|
|
}
|
|
|
|
UInt32 flexNetAddress;
|
|
if (Conversion.TryParseHexOrDecString(windowViewModel.DeviceId, out flexNetAddress))
|
|
{
|
|
Ping_NA2WDataReport_NA2WWater_TimeValues dataReport = new Ping_NA2WDataReport_NA2WWater_TimeValues();
|
|
|
|
ClassicNA2WCommandFrame commandFrame = new ClassicNA2WCommandFrame(dataReport);
|
|
commandFrame.FlexNetID = flexNetAddress;
|
|
SerialRadioFrameMessage radioFrame = new SerialRadioFrameMessage(commandFrame);
|
|
radioFrame.RadioFrameType = RadioFrameType.FlexNetV1;
|
|
SendNa2wSerial(radioFrame);
|
|
}
|
|
}
|
|
else if (type.Equals("CustomPam"))
|
|
{
|
|
UInt32 sensusRfAddress;
|
|
String pamPayload = windowViewModel.PamPayload.Trim();
|
|
|
|
if (Conversion.TryParseHexOrDecString(windowViewModel.DeviceId, out sensusRfAddress))
|
|
{
|
|
byte[] pamPayloadArray = ByteArray.FromHexString(pamPayload);
|
|
|
|
// Add authorization
|
|
String authLevel = windowViewModel.SRfAuthSelectedItem;
|
|
pamPayloadArray = PrependAuthLevel(pamPayloadArray, authLevel);
|
|
|
|
byte[] srfCmdFrame = BuildSensusRFPam(sensusRfAddress, pamPayloadArray);
|
|
|
|
SerialRadioFrameMessage radioFrame = new SerialRadioFrameMessage(new Frame(srfCmdFrame));
|
|
radioFrame.RadioFrameType = RadioFrameType.SensusRF;
|
|
SendNa2wSerial(radioFrame);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TestTotalizerCommand(String type)
|
|
{
|
|
if (type.Equals("Reset"))
|
|
{
|
|
TestTotalizer testTotalizer =
|
|
new TestTotalizer();
|
|
testTotalizer.Value = 0;
|
|
|
|
List<NA2WParameter> na2wParamList = new List<NA2WParameter>();
|
|
na2wParamList.Add(testTotalizer);
|
|
|
|
ParameterWriteCommand parameterWriteCommand = new ParameterWriteCommand(na2wParamList);
|
|
parameterWriteCommand.TagMap = (TagMap)5;
|
|
|
|
SendNa2wSerial(parameterWriteCommand, false);
|
|
}
|
|
}
|
|
|
|
public void SendHandshake()
|
|
{
|
|
// Send Factory Sleep Open command
|
|
FactoryTestOpen factoryTestOpen = new FactoryTestOpen();
|
|
factoryTestOpen.SleepTime = GlobalIPerlUtility.Properties.Settings.Default.SleepTime;
|
|
|
|
SendNa2wSerial(factoryTestOpen, ParameterReadResponse._Code);
|
|
}
|
|
|
|
void MessageReceived(object sender, ReceptionEventArgs<ISerialMessageFrame> args)
|
|
{
|
|
ISerialMessageFrame message = args.Frame;
|
|
|
|
LogIncoming(message);
|
|
|
|
if (message.Payload is ParameterReadResponse)
|
|
{
|
|
ParameterReadResponse parameterReadResponse = (ParameterReadResponse)message.Payload;
|
|
|
|
if (parameterReadResponse.TagMap == TagMap.GlobalIPerl)
|
|
{
|
|
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
|
|
|
|
foreach (NA2WParameter na2wParameter in na2wParameterList)
|
|
{
|
|
switch (na2wParameter.Tag)
|
|
{
|
|
case ((byte)GlobalIPerlTag.SerialNumber):
|
|
windowViewModel.SerialNumber = na2wParameter.Value.Read<UInt64>(0).ToString();
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.DeviceId):
|
|
UInt32 deviceId = na2wParameter.Value.Read<UInt32>(0);
|
|
if (0xefffffff == deviceId)
|
|
{
|
|
windowViewModel.DeviceId = "0xEFFFFFFF";
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.DeviceId = deviceId.ToString();
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.TcxoCorrection):
|
|
windowViewModel.TcxoCorrection = na2wParameter.Value.Read<Int16>(0).ToString();
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.PcbVariantId):
|
|
windowViewModel.PcbVariantId = na2wParameter.Value[0];
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.PcbVariantIdAdc):
|
|
windowViewModel.PcbVariantIdAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.InitialPcbVariantIdAdc):
|
|
windowViewModel.InitialPcbVariantIdAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ProductTypeVersion):
|
|
String productTypeVersion = "R";
|
|
if (0x80 == (na2wParameter.Value[1] & 0x80))
|
|
{
|
|
productTypeVersion = "B";
|
|
}
|
|
productTypeVersion += ((uint)((na2wParameter.Value[1] & 0x70) >> 4)).ToString("X1") + ".";
|
|
productTypeVersion += ((uint)(na2wParameter.Value[1] & 0x0f)).ToString("X1") + ".";
|
|
productTypeVersion += na2wParameter.Value[0].ToString("X2");
|
|
windowViewModel.ProductTypeVersion = productTypeVersion;
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.RfPowerLevel):
|
|
windowViewModel.RfPowerLevel = "0x" + na2wParameter.Value.Read<Byte>(0).ToString("X2") + " (" + na2wParameter.Value.Read<Byte>(0).ToString() + ")";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ProductType):
|
|
windowViewModel.ProductType = na2wParameter.Value[0];
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.Capabilities):
|
|
{
|
|
string capabilities = "";
|
|
if (na2wParameter.Value.Read<bool>(0, 1)) { capabilities += "FNv1 "; }
|
|
if (na2wParameter.Value.Read<bool>(1, 1)) { capabilities += "FNv2 "; }
|
|
if (na2wParameter.Value.Read<bool>(2, 1)) { capabilities += "SRF "; }
|
|
if (na2wParameter.Value.Read<bool>(3, 1)) { capabilities += "WMBUS "; }
|
|
if (na2wParameter.Value.Read<bool>(4, 1)) { capabilities += "NFC "; }
|
|
if (na2wParameter.Value.Read<bool>(5, 1)) { capabilities += "NFC-FN "; }
|
|
if (na2wParameter.Value.Read<bool>(6, 1)) { capabilities += "ASK-TX "; }
|
|
if (na2wParameter.Value.Read<bool>(7, 1)) { capabilities += "TR "; }
|
|
if (na2wParameter.Value.Read<bool>(8, 1)) { capabilities += "ML-TX"; }
|
|
capabilities = capabilities.Trim();
|
|
capabilities = capabilities.Replace(' ', ',');
|
|
windowViewModel.Capabilities = capabilities;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.Mode):
|
|
{
|
|
string mode = "";
|
|
int systemState = na2wParameter.Value.Read<byte>(0, 5);
|
|
int topLevelState = na2wParameter.Value.Read<byte>(5, 2);
|
|
int cellularState = na2wParameter.Value.Read<byte>(7, 4);
|
|
bool factoryFlag = na2wParameter.Value.Read<bool>(11);
|
|
bool debugBlockFlag = na2wParameter.Value.Read<bool>(12);
|
|
|
|
if ((systemState & 1) != 0) mode += "P ";
|
|
else if ((systemState & 2) != 0) mode += "S ";
|
|
else if ((systemState & 4) != 0) mode += "A ";
|
|
else if ((systemState & 8) != 0) mode += "D ";
|
|
else if ((systemState & 16) != 0) mode += "E ";
|
|
else mode += "? ";
|
|
|
|
if (0 == topLevelState) mode += "I ";
|
|
else if (1 == topLevelState) mode += "W ";
|
|
else if (2 == topLevelState) mode += "L ";
|
|
else if (3 == topLevelState) mode += "M ";
|
|
|
|
if ((cellularState & 7) == 0) mode += "! ";
|
|
else if ((cellularState & 7) == 1) mode += "C ";
|
|
else if ((cellularState & 7) == 2) mode += "r ";
|
|
else if ((cellularState & 7) == 3) mode += "R ";
|
|
else if ((cellularState & 7) == 4) mode += "T ";
|
|
else if ((cellularState & 7) == 5) mode += "F ";
|
|
else mode += "? ";
|
|
|
|
|
|
if (factoryFlag) mode += "FT ";
|
|
if (debugBlockFlag) mode += "DB ";
|
|
|
|
mode = mode.Trim();
|
|
windowViewModel.Mode = mode;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.SystemTime):
|
|
{
|
|
windowViewModel.SystemTime = "0x" + na2wParameter.Value.Read<UInt64>(0).ToString("X8");
|
|
break;
|
|
}
|
|
|
|
case ((byte)GlobalIPerlTag.ProductTime):
|
|
{
|
|
windowViewModel.ProductTime = na2wParameter.Value.Read<UInt32>(0).ToString() + " secs";
|
|
break;
|
|
}
|
|
|
|
case ((byte)GlobalIPerlTag.Temperature):
|
|
windowViewModel.Temperature = ((sbyte)(na2wParameter.Value[0])).ToString() + "C";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.TemperatureAdc):
|
|
windowViewModel.TemperatureAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
|
|
windowViewModel.Temperature = ((sbyte)(na2wParameter.Value[2])).ToString() + "C";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.TemperatureCalibration):
|
|
windowViewModel.TemperatureCalOffset = (sbyte)(na2wParameter.Value[0]);
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.Vbat):
|
|
windowViewModel.Vbat = ((double)(na2wParameter.Value.Read<UInt16>(0)) / 1000).ToString("F3") + "V";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.VbatAdc):
|
|
windowViewModel.VbatAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
|
|
windowViewModel.Vbat = ((double)(na2wParameter.Value.Read<UInt16>(16)) / 1000).ToString("F3") + "V";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.VbatCalibration):
|
|
windowViewModel.VbatCalOffset = (sbyte)(na2wParameter.Value[0]);
|
|
windowViewModel.VbatCalSlope = na2wParameter.Value.Read<UInt16>(8);
|
|
break;
|
|
|
|
|
|
case ((byte)GlobalIPerlTag.Vsys):
|
|
windowViewModel.Vsys = ((double)(na2wParameter.Value.Read<UInt16>(0)) / 1000).ToString("F3") + "V";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.VsysAdc):
|
|
windowViewModel.VsysAdc = "0x" + na2wParameter.Value.Read<UInt16>(0).ToString("X4");
|
|
windowViewModel.Vsys = ((double)(na2wParameter.Value.Read<UInt16>(16)) / 1000).ToString("F3") + "V";
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.VsysCalibration):
|
|
windowViewModel.VsysCalOffset = (sbyte)(na2wParameter.Value[0]);
|
|
windowViewModel.VsysCalSlope = na2wParameter.Value.Read<UInt16>(8);
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ProcessorId):
|
|
string uuid = "";
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
uuid += na2wParameter.Value[i].ToString("X2") + " ";
|
|
}
|
|
windowViewModel.ProcessorUuid = uuid;
|
|
|
|
if (na2wParameter.Value.Length >= 20)
|
|
{
|
|
windowViewModel.ProcessorFlashSize = na2wParameter.Value.Read<UInt16>(16 * 8, 16).ToString() + "kB";
|
|
windowViewModel.ProcessorRamSize = na2wParameter.Value.Read<UInt16>(18 * 8, 16).ToString() + "kB";
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.ProcessorFlashSize = "";
|
|
windowViewModel.ProcessorRamSize = "";
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.TransceiverId):
|
|
{
|
|
string id = "";
|
|
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
|
|
id += String.Format("{0}.{1}.{2}.{3}", na2wParameter.Value[1], na2wParameter.Value[2], na2wParameter.Value[3], na2wParameter.Value[4]);
|
|
windowViewModel.RadioChip = id;
|
|
}
|
|
break;
|
|
|
|
|
|
case ((byte)GlobalIPerlTag.SerialFlashId):
|
|
{
|
|
string id = "";
|
|
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
|
|
id += na2wParameter.Value[1].ToString("X2") + na2wParameter.Value[2].ToString("X2") + "-"; // Part
|
|
id += na2wParameter.Value[3].ToString("X2"); // Revision
|
|
windowViewModel.SerialFlashId = id;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.NfcTagId):
|
|
{
|
|
string id = "";
|
|
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
|
|
id += na2wParameter.Value[1].ToString("X2") + na2wParameter.Value[2].ToString("X2") + "-"; // Part
|
|
id += na2wParameter.Value[3].ToString("X2") + "-"; // Revision
|
|
// UUID
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
id += na2wParameter.Value[4 + i].ToString("X2") + " ";
|
|
}
|
|
windowViewModel.NfcTagId = id;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.MetrologyId):
|
|
{
|
|
string id = "";
|
|
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
|
|
id += na2wParameter.Value[1].ToString("X2"); // Revision
|
|
windowViewModel.MetrologyId = id;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.SecurityCoprocessorId):
|
|
{
|
|
string id = "";
|
|
id += na2wParameter.Value[0].ToString("X2") + "-"; // Family
|
|
id += String.Format("{0}.{1}.{2}.{3}", na2wParameter.Value[1], na2wParameter.Value[2], na2wParameter.Value[3], na2wParameter.Value[4]);
|
|
windowViewModel.SecurityCoprocessorId = id;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.Reading):
|
|
{
|
|
UInt32 billingVolume = na2wParameter.Value.Read<UInt32>(16 * 0, 32);
|
|
byte units = (byte)(na2wParameter.Value[4]);
|
|
string reading = billingVolume.ToString() + " ";
|
|
if (units == 19)
|
|
{
|
|
reading += "l";
|
|
}
|
|
else
|
|
{
|
|
reading += "(" + units + ")";
|
|
}
|
|
|
|
reading = reading.Trim();
|
|
windowViewModel.Reading = reading;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.Alarms):
|
|
{
|
|
string alarms = "";
|
|
if ((na2wParameter.Value[0] & 0x01) != 0) alarms += "wMB ";
|
|
if ((na2wParameter.Value[0] & 0x02) != 0) alarms += "MA ";
|
|
if ((na2wParameter.Value[0] & 0x04) != 0) alarms += "BP ";
|
|
if ((na2wParameter.Value[0] & 0x08) != 0) alarms += "Bf ";
|
|
if ((na2wParameter.Value[0] & 0x10) != 0) alarms += "MetUn ";
|
|
if ((na2wParameter.Value[0] & 0x20) != 0) alarms += "MT ";
|
|
if ((na2wParameter.Value[0] & 0x40) != 0) alarms += "Leak ";
|
|
if ((na2wParameter.Value[0] & 0x80) != 0) alarms += "LBat ";
|
|
alarms = alarms.Trim();
|
|
alarms = alarms.Replace(' ', ',');
|
|
windowViewModel.Alarms = alarms;
|
|
}
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ActivityCredits):
|
|
windowViewModel.ActivityCredits = na2wParameter.Value.Read<UInt16>(0).ToString();
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ManufacturingNote):
|
|
windowViewModel.ManufacturingNote = na2wParameter.Value.Read<string>(0, 64 * 8);
|
|
break;
|
|
|
|
case ((byte)GlobalIPerlTag.ResetInfo):
|
|
{
|
|
UInt16 totalResetCount = na2wParameter.Value.Read<UInt16>(0);
|
|
UInt16 wdResetCount = na2wParameter.Value.Read<UInt16>(16);
|
|
UInt16 swResetCount = na2wParameter.Value.Read<UInt16>(32);
|
|
UInt16 fwdlResetCount = na2wParameter.Value.Read<UInt16>(48);
|
|
UInt32 lastResetCause = na2wParameter.Value.Read<UInt32>(64);
|
|
|
|
windowViewModel.ResetInfo = "Cnt: " + String.Format("{0:00000} ", totalResetCount);
|
|
windowViewModel.ResetInfo += "WD: " + String.Format("{0:00000} ", wdResetCount);
|
|
windowViewModel.ResetInfo += "SW: " + String.Format("{0:00000} ", swResetCount);
|
|
windowViewModel.ResetInfo += "UPG: " + String.Format("{0:00000} ", fwdlResetCount);
|
|
|
|
String lastResetCauseName = "Unknown";
|
|
// Convert to FG2x causes
|
|
switch (lastResetCause)
|
|
{
|
|
case (1 << 0):
|
|
lastResetCauseName = "Power On";
|
|
break;
|
|
case (1 << 1):
|
|
lastResetCauseName = "External Pin";
|
|
break;
|
|
case (1 << 2):
|
|
lastResetCauseName = "EM4";
|
|
break;
|
|
case (1 << 3):
|
|
lastResetCauseName = "Watchdog 0";
|
|
break;
|
|
case (1 << 4):
|
|
lastResetCauseName = "Watchdog 1";
|
|
break;
|
|
case (1 << 5):
|
|
lastResetCauseName = "Lockup";
|
|
break;
|
|
case (1 << 6):
|
|
lastResetCauseName = "System Request";
|
|
break;
|
|
case (1 << 7):
|
|
lastResetCauseName = "BOD DVDD";
|
|
break;
|
|
case (1 << 8):
|
|
lastResetCauseName = "BOD DVDD LE";
|
|
break;
|
|
case (1 << 9):
|
|
lastResetCauseName = "BOD Decouple";
|
|
break;
|
|
case (1 << 10):
|
|
lastResetCauseName = "BOD AVDD";
|
|
break;
|
|
case (1 << 11):
|
|
lastResetCauseName = "BOD IOVDD";
|
|
break;
|
|
case ((uint)1 << 31):
|
|
lastResetCauseName = "DCDC VREGIN";
|
|
break;
|
|
}
|
|
windowViewModel.ResetInfo += "Last Reason: " + lastResetCauseName;
|
|
}
|
|
break;
|
|
|
|
|
|
case ((byte)GlobalIPerlTag.FlashCrc):
|
|
{
|
|
UInt16 crc = na2wParameter.Value.Read<ushort>(0);
|
|
windowViewModel.FlashCrc = crc;
|
|
break;
|
|
}
|
|
|
|
case ((byte)GlobalIPerlTag.RHumidId):
|
|
{
|
|
windowViewModel.RHumidId = "" + (char)na2wParameter.Value.Read<sbyte>(8) + (char)na2wParameter.Value.Read<sbyte>(0)
|
|
+ (na2wParameter.Value[2] | na2wParameter.Value[3] << 8);
|
|
break;
|
|
}
|
|
|
|
case ((byte)GlobalIPerlTag.RHumid):
|
|
{
|
|
windowViewModel.RHumid = na2wParameter.Value.Read<sbyte>(0).ToString() + "%";
|
|
break;
|
|
}
|
|
|
|
case ((byte)GlobalIPerlTag.RHumidCalOffset):
|
|
{
|
|
windowViewModel.RHumidCalOffset = na2wParameter.Value.Read<sbyte>(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Look for factory handshake: ParameterRead with 2 parameters - Product Type and Product Type Version
|
|
if ((2 == na2wParameterList.Count)
|
|
&& (na2wParameterList[0].Tag == (byte)GlobalIPerlTag.ProductType)
|
|
&& (na2wParameterList[1].Tag == (byte)GlobalIPerlTag.ProductTypeVersion)
|
|
)
|
|
{
|
|
if (windowViewModel.IsFactoryHandshakeEnabled)
|
|
{
|
|
Thread t = new Thread(new ThreadStart(SendHandshake));
|
|
t.Start();
|
|
}
|
|
}
|
|
}
|
|
if (parameterReadResponse.TagMap == (TagMap)0x05)
|
|
{
|
|
List<NA2WParameter> na2wParameterList = parameterReadResponse.Parameters;
|
|
|
|
foreach (NA2WParameter na2wParameter in na2wParameterList)
|
|
{
|
|
switch (na2wParameter.Tag)
|
|
{
|
|
case ((byte)SterlingMetrologyTag.FactoryId):
|
|
const byte FACTORY_ID_NUM_BYTES = (12);
|
|
windowViewModel.FactoryId = na2wParameter.Value.Read<string>(0 * 8, FACTORY_ID_NUM_BYTES * 8);
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.CustomerId):
|
|
const byte CUSTOMER_ID_NUM_BYTES = (12);
|
|
windowViewModel.CustomerId = na2wParameter.Value.Read<string>(0 * 8, CUSTOMER_ID_NUM_BYTES * 8);
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.BuildInformation):
|
|
const byte BUILD_INFO_NUM_BYTES = (14);
|
|
windowViewModel.BuildInfo = na2wParameter.Value.Read<string>(0 * 8, BUILD_INFO_NUM_BYTES * 8);
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.ManufactureDate):
|
|
{
|
|
UInt32 manufactureDate = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
|
|
|
|
windowViewModel.ManufactureDate = manufactureDate.ToString();
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.CalibrationStatus):
|
|
String fwVersion = "R";
|
|
if (0x80 == (na2wParameter.Value[6] & 0x80))
|
|
{
|
|
fwVersion = "B";
|
|
}
|
|
fwVersion += ((uint)((na2wParameter.Value[6] & 0x70) >> 4)).ToString("X1") + ".";
|
|
fwVersion += ((uint)(na2wParameter.Value[6] & 0x0f)).ToString("X1") + ".";
|
|
fwVersion += na2wParameter.Value[5].ToString("X2");
|
|
|
|
String calibrationStatus =
|
|
String.Format(
|
|
"{0} {1} {2} {3}",
|
|
na2wParameter.Value.Read<Byte>(0 * 8),
|
|
na2wParameter.Value.Read<UInt32>(1 * 8),
|
|
fwVersion,
|
|
na2wParameter.Value.Read<UInt32>(7 * 8)
|
|
);
|
|
windowViewModel.SterlingCalibrationStatus = calibrationStatus;
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.Reading):
|
|
{
|
|
UInt32 totalizer = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
|
|
windowViewModel.Reading_Totalizer = totalizer.ToString("D9");
|
|
sbyte digits = na2wParameter.Value.Read<sbyte>(4 * 8, 8);
|
|
windowViewModel.Reading_Digits = digits.ToString();
|
|
sbyte shift = na2wParameter.Value.Read<sbyte>(5 * 8, 8);
|
|
windowViewModel.Reading_Shift = shift.ToString();
|
|
sbyte resolution = na2wParameter.Value.Read<sbyte>(6 * 8, 8);
|
|
windowViewModel.Reading_Resolution = resolution.ToString();
|
|
|
|
double billing = totalizer;
|
|
billing *= Math.Pow(10, resolution);
|
|
UInt32 billingNumber = (UInt32)billing;
|
|
UInt32 billingFraction = (UInt32)( totalizer - (billingNumber * Math.Pow(10, -resolution) ) );
|
|
String billingNumberString = billingNumber.ToString("000000000");
|
|
String billingFractionString = billingFraction.ToString("000000000");
|
|
int resolutionLocation = -resolution;
|
|
int amrStartLocation = -shift;
|
|
int clip = 9 - (digits - (resolutionLocation - amrStartLocation) );
|
|
if (clip > 0) billingNumberString = billingNumberString.Substring(clip);
|
|
int fractionDigits = resolutionLocation - amrStartLocation;
|
|
if (resolutionLocation > 0) billingFractionString = billingFractionString.Substring(9 - resolutionLocation);
|
|
if (fractionDigits > 0) billingFractionString = billingFractionString.Substring(0, fractionDigits);
|
|
windowViewModel.Reading = billingNumberString + "." + billingFractionString;
|
|
|
|
windowViewModel.Reading_Units = na2wParameter.Value.Read<byte>(7 * 8, 8).ToString();
|
|
windowViewModel.Reading_FlowDirection = na2wParameter.Value.Read<sbyte>(8 * 8, 8).ToString();
|
|
windowViewModel.Reading_FlowRate = na2wParameter.Value.Read<Int16>(9 * 8, 16).ToString();
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.MeterState):
|
|
{
|
|
byte meterState = na2wParameter.Value.Read<byte>(0, 8);
|
|
String meterStateString = String.Format("0x{0:X2} - Unknown", meterState);
|
|
foreach (MeterStateComboBoxItem meterStateComboBoxItem in windowViewModel.MeterStateCollection)
|
|
{
|
|
if (meterStateComboBoxItem.Value == meterState)
|
|
{
|
|
meterStateString = meterStateComboBoxItem.Name;
|
|
break;
|
|
}
|
|
}
|
|
windowViewModel.SterlingMeterState = meterStateString;
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.OpticalDataMode):
|
|
{
|
|
byte mode = na2wParameter.Value.Read<byte>(0, 8);
|
|
String opticalDataModeString = String.Format("0x{0:X2} - Unknown", mode);
|
|
foreach (OpticalModeComboBoxItem opticalModeComboBoxItem in windowViewModel.OpticalModeCollection)
|
|
{
|
|
if (opticalModeComboBoxItem.Value == mode)
|
|
{
|
|
opticalDataModeString = opticalModeComboBoxItem.Name;
|
|
break;
|
|
}
|
|
}
|
|
windowViewModel.OpticalDataMode = opticalDataModeString;
|
|
break;
|
|
}
|
|
|
|
case ((byte)SterlingMetrologyTag.DisplayTimeout):
|
|
{
|
|
windowViewModel.DisplayTimeout = na2wParameter.Value.Read<byte>(0 * 8).ToString();
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.TestTotalizer):
|
|
{
|
|
UInt32 testTotalizer = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
|
|
|
|
windowViewModel.TestTotalizer = testTotalizer.ToString("D9");
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.Temperature):
|
|
{
|
|
Int16 temperature_tC = na2wParameter.Value.Read<Int16>(0 * 8, 16);
|
|
double temperature_C = (temperature_tC / 10.0); // Convert reading to just degrees C
|
|
windowViewModel.ASICTemperature = temperature_C.ToString() + "C";
|
|
Int16 temperatureMax_tC = na2wParameter.Value.Read<Int16>(2 * 8, 16);
|
|
double temperatureMax_C = (temperatureMax_tC / 10.0); // Convert reading to just degrees C
|
|
windowViewModel.ASICTemperatureMax = temperatureMax_C.ToString() + "C";
|
|
Int16 temperatureMin_tC = na2wParameter.Value.Read<Int16>(4 * 8, 16);
|
|
double temperatureMin_C = (temperatureMin_tC / 10.0); // Convert reading to just degrees C
|
|
windowViewModel.ASICTemperatureMin = temperatureMin_C.ToString() + "C";
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.TemperatureAdc):
|
|
{
|
|
UInt16 temperatureAdc = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
|
|
windowViewModel.ASICTemperatureAdc = "0x" + temperatureAdc.ToString("X4");
|
|
Int16 Temperature_tC = na2wParameter.Value.Read<Int16>(2 * 8, 16);
|
|
double Temperature_C = (Temperature_tC / 10.0); // Convert reading to just degrees C
|
|
windowViewModel.ASICTemperature = Temperature_C.ToString() + "C";
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.TemperatureCalibration):
|
|
{
|
|
Int16 temperatureCal = na2wParameter.Value.Read<Int16>(0 * 8, 16);
|
|
windowViewModel.ASICTemperatureCalibration = temperatureCal;
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.Vbat):
|
|
{
|
|
UInt16 vbat_mV = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
|
|
double vbat_V = ((double)vbat_mV / 1000.0); // Convert reading from mV to just V
|
|
windowViewModel.ASICVbat = vbat_V.ToString("F3") + "V";
|
|
UInt16 vbatMax_mV = na2wParameter.Value.Read<UInt16>(2 * 8, 16);
|
|
double vbatMax_V = ((double)vbatMax_mV / 1000.0); // Convert reading from mV to just V
|
|
windowViewModel.ASICVbatMax = vbatMax_V.ToString("F3") + "V";
|
|
UInt16 vbatMin_mV = na2wParameter.Value.Read<UInt16>(4 * 8, 16);
|
|
double vbatMin_V = ((double)vbatMin_mV / 1000.0); // Convert reading from mV to just V
|
|
windowViewModel.ASICVbatMin = vbatMin_V.ToString("F3") + "V";
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.VbatAdc):
|
|
{
|
|
UInt16 vbatAdc = na2wParameter.Value.Read<UInt16>(0 * 8, 16);
|
|
windowViewModel.ASICVbatAdc = "0x" + vbatAdc.ToString("X4");
|
|
UInt16 vbat_mV = na2wParameter.Value.Read<UInt16>(2 * 8, 16);
|
|
double vbat_V = ((double)vbat_mV / 1000.0); // Convert reading from mV to just V
|
|
windowViewModel.ASICVbat = vbat_V.ToString("F3") + "V";
|
|
}
|
|
break;
|
|
|
|
case (byte)SterlingMetrologyTag.DisplaySwitchAdc:
|
|
{
|
|
UInt32 reading = na2wParameter.Value.Read<UInt32>(0 * 8, 32);
|
|
windowViewModel.DisplaySwitchReading = "0x" + reading.ToString("X8");
|
|
Byte state = na2wParameter.Value.Read<Byte>(4 * 8, 8);
|
|
if (1 == state)
|
|
{
|
|
windowViewModel.DisplaySwitchState = String.Format("Closed (0x{0,2:X2})", state);
|
|
}
|
|
else if (2 == state)
|
|
{
|
|
windowViewModel.DisplaySwitchState = String.Format("Opened (0x{0,2:X2})", state);
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.DisplaySwitchState = String.Format("Unknown (0x{0,2:X2})", state);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.EmptyPipeParameters):
|
|
windowViewModel.EPParam_ImpedanceThreshold = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
|
|
windowViewModel.EPParam_EmptyTimeThreshold = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
|
|
windowViewModel.EPParam_HydrationDuration = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.MagneticFieldDriveParameters):
|
|
windowViewModel.MFDParam_DriveTime = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
|
|
windowViewModel.MFDParam_FieldFitA0 = na2wParameter.Value.Read<Int32>(1 * 8).ToString();
|
|
windowViewModel.MFDParam_FieldFitA1 = na2wParameter.Value.Read<Int32>(5 * 8).ToString();
|
|
windowViewModel.MFDParam_FieldDriveStepMagnitude = na2wParameter.Value.Read<UInt16>(9 * 8).ToString();
|
|
windowViewModel.MFDParam_FieldControlHysteresis_mG = na2wParameter.Value.Read<UInt16>(11 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.MagneticTamperParameters):
|
|
windowViewModel.MTParam_MaxPercentError = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
|
|
windowViewModel.MTParam_DetectionCounts = na2wParameter.Value.Read<Byte>(1 * 8).ToString();
|
|
windowViewModel.MTParam_PidSettlingTime = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
|
|
windowViewModel.MTParam_DriveLow = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
|
|
windowViewModel.MTParam_DriveHigh = na2wParameter.Value.Read<Byte>(4 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.ReverseVolumeBufferParameters):
|
|
windowViewModel.RVBParam_Threshold_qml = na2wParameter.Value.Read<UInt32>(0 * 8).ToString();
|
|
windowViewModel.RVBParam_Leak_qml_s = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.InputRangeParameters):
|
|
windowViewModel.IRParam_AdcRailingHighThreshold = na2wParameter.Value.Read<UInt32>(0 * 8).ToString();
|
|
windowViewModel.IRParam_AdcRailingLowThreshold = na2wParameter.Value.Read<UInt32>(4 * 8).ToString();
|
|
windowViewModel.IRParam_MaxAdcThreshold = na2wParameter.Value.Read<UInt32>(8 * 8).ToString();
|
|
windowViewModel.IRParam_MaxElectrodeDelta = na2wParameter.Value.Read<UInt16>(12 * 8).ToString();
|
|
windowViewModel.IRParam_EmfAlarmHoldoffHours = na2wParameter.Value.Read<Byte>(14 * 8).ToString();
|
|
windowViewModel.IRParam_AdcNoiseThreshold = na2wParameter.Value.Read<UInt16>(15 * 8).ToString();
|
|
windowViewModel.IRParam_RawImpedanceClamp = na2wParameter.Value.Read<UInt32>(17 * 8).ToString();
|
|
windowViewModel.IRParam_MaxFlowRate = na2wParameter.Value.Read<UInt16>(21 * 8).ToString();
|
|
windowViewModel.IRParam_MaxFlowRateAlarmCount = na2wParameter.Value.Read<Byte>(23 * 8).ToString();
|
|
windowViewModel.IRParam_FlowRateStdDevInvSlope = na2wParameter.Value.Read<Byte>(24 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.LowFlowParameters):
|
|
windowViewModel.LFParam_EntryRate = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
|
|
windowViewModel.LFParam_EntryTime = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
|
|
windowViewModel.LFParam_ExitRate = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
|
|
windowViewModel.LFParam_ExitTime = na2wParameter.Value.Read<UInt16>(6 * 8).ToString();
|
|
windowViewModel.LFParam_LowPowerDelay_min = na2wParameter.Value.Read<Byte>(8 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.ImpedanceDriveParameters):
|
|
windowViewModel.IDParam_DriveStrength = na2wParameter.Value.Read<Byte>(0 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.CalibrationFactor):
|
|
windowViewModel.CalibrationFactor = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.ZeroFlowOffsetParameters):
|
|
windowViewModel.ZFParam_ZeroFlowOffset = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
|
|
windowViewModel.ZFParam_ZeroFlowOffsetThreshold = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.TargetFieldParameters):
|
|
windowViewModel.TFParam_NormalPowerTargetField = na2wParameter.Value.Read<UInt16>(0 * 8).ToString();
|
|
windowViewModel.TFParam_LowPowerTargetField = na2wParameter.Value.Read<UInt16>(2 * 8).ToString();
|
|
windowViewModel.TFParam_HighPowerTargetField = na2wParameter.Value.Read<UInt16>(4 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.SpreadSpectrumParameters):
|
|
windowViewModel.SSParam_DisableSpreadSpectrum = na2wParameter.Value.Read<Boolean>(0, 1).ToString();
|
|
windowViewModel.SSParam_AlwaysUseFullRateBags = na2wParameter.Value.Read<Boolean>(1, 1).ToString();
|
|
windowViewModel.SSParam_PowerUp = na2wParameter.Value.Read<Byte>(1 * 8).ToString();
|
|
windowViewModel.SSParam_HighNoise = na2wParameter.Value.Read<Byte>(2 * 8).ToString();
|
|
windowViewModel.SSParam_EmptyPipe = na2wParameter.Value.Read<Byte>(3 * 8).ToString();
|
|
windowViewModel.SSParam_BadAdc = na2wParameter.Value.Read<Byte>(4 * 8).ToString();
|
|
windowViewModel.SSParam_InitLearningCompleteCount = na2wParameter.Value.Read<UInt16>(5 * 8).ToString();
|
|
windowViewModel.SSParam_MinOffsetLearningSampleCount = na2wParameter.Value.Read<UInt16>(7 * 8).ToString();
|
|
windowViewModel.SSParam_AdcShiftUpdateInterval = na2wParameter.Value.Read<Byte>(9 * 8).ToString();
|
|
windowViewModel.SSParam_MaxPreviousAdcAge = na2wParameter.Value.Read<Byte>(10 * 8).ToString();
|
|
windowViewModel.SSParam_AdcOffsetLearningGuard = na2wParameter.Value.Read<UInt16>(11 * 8).ToString();
|
|
windowViewModel.SSParam_DisplacementCorrectionCount = na2wParameter.Value.Read<Byte>(13 * 8).ToString();
|
|
break;
|
|
|
|
case ((byte)SterlingMetrologyTag.MeterSize):
|
|
{
|
|
byte meterSize = na2wParameter.Value.Read<byte>(0, 8);
|
|
String meterSizeString = String.Format("0x{0:X2} - Unknown", meterSize);
|
|
foreach (MeterSizeComboBoxItem meterSizeComboBoxItem in windowViewModel.MeterSizeCollection)
|
|
{
|
|
if (meterSizeComboBoxItem.Value == meterSize)
|
|
{
|
|
meterSizeString = meterSizeComboBoxItem.Name;
|
|
break;
|
|
}
|
|
}
|
|
windowViewModel.SterlingMeterSize = meterSizeString;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (message.Payload is SerialRadioFrameMessage)
|
|
{
|
|
SerialRadioFrameMessage serialRadioFrameMessage = (SerialRadioFrameMessage)message.Payload;
|
|
|
|
string timeStamp = DateTime.Now.ToLongTimeString(); // serialRadioReceiveMessageV1.TimeStamp.ToString();
|
|
|
|
string description = "";
|
|
ChannelizedFlexNetId channelizedFlexNetId = new ChannelizedFlexNetId();
|
|
|
|
if ((serialRadioFrameMessage.Payload is ClassicFlexNetMessageFrame) || ((SyncWord)serialRadioFrameMessage.Payload.ToArray().Read<UInt16>(0, 16) == SyncWord.Classic))
|
|
{
|
|
description = "Classic";
|
|
|
|
ClassicFlexNetMessageFrame frame = ClassicFlexNetMessageFrame.Parse(serialRadioFrameMessage.Payload.ToArray(), 0);
|
|
|
|
channelizedFlexNetId.ID = frame.FlexNetID;
|
|
channelizedFlexNetId.Channel = 0;
|
|
|
|
description += ", " + frame.FlexNetID;
|
|
description += ", " + String.Format("0x{0:X2} (", frame.AppCode) + frame.AppCode + ")";
|
|
description += frame.Payload.ToString();
|
|
}
|
|
else
|
|
{
|
|
byte[] payload = serialRadioFrameMessage.Payload.ToBytes();
|
|
if (payload.Length > 9)
|
|
{
|
|
SyncWord syncWord = (SyncWord)payload.Read<UInt16>(0, 16);
|
|
FlexType flexType = (FlexType)payload.Read<byte>(16, 4);
|
|
|
|
if (
|
|
(syncWord == SyncWord.Classic)
|
|
|| ((syncWord == SyncWord.GFSK) && (flexType == FlexType.NALinePowered))
|
|
)
|
|
{
|
|
UInt32 flexNetId = payload.Read<UInt32>(32, 28);
|
|
bool downlinkFlag = payload.Read<bool>(64, 1);
|
|
description = "FT1, " + (downlinkFlag ? "DL, " : "UL, ") + flexNetId;
|
|
|
|
channelizedFlexNetId.ID = flexNetId;
|
|
}
|
|
else if ((syncWord == (SyncWord)0xc5ac) && (flexType == (FlexType)10))
|
|
{
|
|
UInt32 TfxId = payload.Read<UInt32>(24, 32);
|
|
bool downlinkFlag = payload.Read<bool>(20, 1);
|
|
|
|
if (15 <= payload.Length)
|
|
{
|
|
byte cmdOrAppCode = payload.Read<byte>(8 * 15, 8);
|
|
if (0xF3 == cmdOrAppCode && 40 <= payload.Length)
|
|
{
|
|
byte version = payload.Read<byte>(8 * 16, 4);
|
|
byte deviceType = payload.Read<byte>(8 * 17, 8);
|
|
UInt32 epochTime = payload.Read<UInt32>(8 * 18, 32);
|
|
byte historySize = payload.Read<byte>(8 * 22, 8);
|
|
byte meterTransmitRate = payload.Read<byte>(8 * 23, 3);
|
|
byte tfxState = payload.Read<byte>(8 * 23 + 3, 2);
|
|
bool activeState = payload.Read<bool>(8 * 23 + 5, 1);
|
|
byte meterSampleRate = payload.Read<byte>(8 * 24 + 5, 3);
|
|
byte meterType = payload.Read<byte>(8 * 25, 4);
|
|
byte readingResolution = payload.Read<byte>(8 * 25 + 4, 4);
|
|
byte encoderDigits = payload.Read<byte>(8 * 26, 3);
|
|
byte historyScale = payload.Read<byte>(8 * 26 + 3, 2);
|
|
byte meterUnits = payload.Read<byte>(8 * 26 + 5, 3);
|
|
byte[] customerSerialNumber = payload.Read<byte[]>(8 * 27, 8 * 13);
|
|
description = "FT10, "
|
|
+ (downlinkFlag ? "DL, " : "UL, ")
|
|
+ TfxId
|
|
+ ", TFX Params, "
|
|
+ $"V:{version},DT:{deviceType},T:{epochTime},HS:{historySize},MTR:{meterTransmitRate},S:{tfxState},A:{activeState},MSR:{meterSampleRate},MT:{meterType},Res:{readingResolution},Dig:{encoderDigits},Scale:{historyScale},Units:{meterUnits}"
|
|
+ $",SN:{ASCIIEncoding.ASCII.GetString(customerSerialNumber).Trim()}";
|
|
}
|
|
else
|
|
{
|
|
description = "FT10, " + (downlinkFlag ? "DL, " : "UL, ") + TfxId + ", " + cmdOrAppCode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = "FT10, " + (downlinkFlag ? "DL, " : "UL, ") + TfxId;
|
|
}
|
|
}
|
|
else if (syncWord == (SyncWord)(0x2504))
|
|
{
|
|
// SensusRF
|
|
byte length = payload[2];
|
|
uint appCodeIndex = 3;
|
|
if (length < 8)
|
|
{
|
|
// No length byte, length fixed to 13 bytes
|
|
length = 13;
|
|
appCodeIndex = 2;
|
|
}
|
|
|
|
Sensus.Protocols.SensusRF.TelegramType telegramType = (Sensus.Protocols.SensusRF.TelegramType)(payload[appCodeIndex]);
|
|
byte counter = payload[appCodeIndex + 1];
|
|
UInt32 radioAddress = payload.Read<UInt32>((appCodeIndex + 2) * 8, 32, ByteOrder.BigEndian);
|
|
|
|
if ((telegramType == Sensus.Protocols.SensusRF.TelegramType.BUPWithLAT) || (telegramType == Sensus.Protocols.SensusRF.TelegramType.BUPWithoutLAT))
|
|
{
|
|
// Buf[0] - App Code
|
|
// Buf[1] - FlexNet Counter
|
|
// Buf[2] - Module Address
|
|
// Buf[3] - Module Address
|
|
// Buf[4] - Module Address
|
|
// Buf[5] - Module Address
|
|
// Buf[6] - Display Volume
|
|
// Buf[7] - Display Volume
|
|
// Buf[8] - Display Volume
|
|
// Buf[9] - Display Volume
|
|
// Buf[10] - Alarms
|
|
// Buf[11] - crc
|
|
// Buf[12] - crc
|
|
|
|
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
|
|
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
|
|
// function appears to work well.
|
|
byte[] encryptedTelegramData = new byte[7];
|
|
Array.Copy(payload, (int)appCodeIndex + 6, encryptedTelegramData, 0, 7);
|
|
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 actualCRC = 0x0000;
|
|
UInt16 expectedCRC = 0xffff;
|
|
byte[] plaintext = new byte[0];
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
}
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
UInt32 volume = plaintext.Read<UInt32>((0) * 8, 32, ByteOrder.BigEndian);
|
|
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + String.Format(" {0:d8} (0x{0:X4})", volume, volume);
|
|
|
|
// Create frame event
|
|
BupReceived(radioAddress, new Frame(plaintext));
|
|
}
|
|
else if (rawActualCRC == 0) // Unencrypted has CRC set to 0
|
|
{
|
|
UInt32 volume = encryptedTelegramData.Read<UInt32>((0) * 8, 32, ByteOrder.BigEndian);
|
|
description = telegramType.ToString() + " (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + String.Format(" {0:d8} (0x{0:X4})", volume, volume);
|
|
|
|
// Create frame event
|
|
BupReceived(radioAddress, new Frame(encryptedTelegramData));
|
|
}
|
|
else
|
|
{
|
|
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed" + ", " + encryptedTelegramData.ToHexString();
|
|
}
|
|
}
|
|
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.PAM)
|
|
{
|
|
// Header
|
|
// byte Length (includes header and payload CRC)
|
|
// byte AppCode - 32 (PAM) - appCodeIndex
|
|
// byte Counter - appCodeIndex + 1
|
|
// UInt32 Address - appCodeIndex + 2, 3, 4, 5
|
|
// UInt16 HeaderCrc - appCodeIndex + 6, 7
|
|
// byte PamCode - 144 (0x90)
|
|
// byte PamLen
|
|
// byte FlexNetFrame[SENSUS_RF_PAM_ENCAP_FLEXNET_FRAME_LENGTH] (46)
|
|
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
|
|
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
|
|
// function appears to work well.
|
|
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
|
|
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
|
|
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
|
|
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 actualCRC = 0x0000;
|
|
UInt16 expectedCRC = 0xffff;
|
|
byte[] plaintext = new byte[0];
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
byte pamCode = plaintext[0];
|
|
|
|
if (pamCode == 144)
|
|
{
|
|
int pamLen = plaintext[1];
|
|
byte[] pamData = new byte[pamLen];
|
|
Array.Copy(plaintext, (int)2, pamData, 0, pamLen);
|
|
|
|
description = "PAM-FN , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamData.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
description = "PAM, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = "PAM, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed" + ", " + encryptedTelegramData.ToHexString();
|
|
}
|
|
}
|
|
else // Assume unencrypted - Data could be garbage
|
|
{
|
|
byte pamCode = encryptedTelegramData[0];
|
|
|
|
if (pamCode == 144)
|
|
{
|
|
int pamLen = encryptedTelegramData[1];
|
|
byte[] pamData = new byte[pamLen];
|
|
Array.Copy(encryptedTelegramData, (int)2, pamData, 0, pamLen);
|
|
|
|
description = "PAM-FN (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamData.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
description = "PAM (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
|
|
}
|
|
}
|
|
}
|
|
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.SEMI)
|
|
{
|
|
// Header
|
|
// byte Length (includes header and payload CRC)
|
|
// byte AppCode - 32 (PAM) - appCodeIndex
|
|
// byte Counter - appCodeIndex + 1
|
|
// UInt32 Address - appCodeIndex + 2, 3, 4, 5
|
|
// UInt16 HeaderCrc - appCodeIndex + 6, 7
|
|
// byte PamCode - 144 (0x90)
|
|
// byte PamLen
|
|
// byte FlexNetFrame[SENSUS_RF_PAM_ENCAP_FLEXNET_FRAME_LENGTH] (46)
|
|
// Decrypt Volume through CRC. Only method I found in Sensus.dll was a static function
|
|
// in TelegramFrame class. TelegramFrame is a serial packet from/to SIRT. The decrypt
|
|
// function appears to work well.
|
|
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
|
|
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
|
|
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
|
|
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 actualCRC = 0x0000;
|
|
UInt16 expectedCRC = 0xffff;
|
|
byte[] plaintext = new byte[0];
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
description = "SEMI, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
|
|
|
|
UInt32 read = plaintext.Read<UInt32>(0 * 8, 32, ByteOrder.BigEndian);
|
|
byte alarms = plaintext.Read<byte>(4 * 8, 8, ByteOrder.BigEndian);
|
|
byte pamStatus = plaintext.Read<byte>(5 * 8, 8, ByteOrder.BigEndian);
|
|
byte pamRssi = plaintext.Read<byte>(6 * 8, 8, ByteOrder.BigEndian);
|
|
byte meterType = plaintext.Read<byte>(7 * 8, 8, ByteOrder.BigEndian);
|
|
|
|
description += String.Format(", MT=0x{0:X2}, Status=0x{1:X2}, RSSI=0x{2:X2}, Read=0x{3:X8}, Alarms=0x{4:X2}", meterType, pamStatus, pamRssi, read, alarms);
|
|
|
|
description += ", " + plaintext.ToHexString();
|
|
|
|
if (meterType == IPerlS4.MeterType)
|
|
{
|
|
SemiReceived(radioAddress, new IPerlS4Semi(plaintext));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = "SEMI, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
|
|
}
|
|
}
|
|
else // Assume unencrypted - Data could be garbage
|
|
{
|
|
description = "SEMI (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
|
|
|
|
UInt32 read = encryptedTelegramData.Read<UInt32>(0 * 8, 32, ByteOrder.BigEndian);
|
|
byte alarms = encryptedTelegramData.Read<byte>(4 * 8, 8, ByteOrder.BigEndian);
|
|
byte pamStatus = encryptedTelegramData.Read<byte>(5 * 8, 8, ByteOrder.BigEndian);
|
|
byte pamRssi = encryptedTelegramData.Read<byte>(6 * 8, 8, ByteOrder.BigEndian);
|
|
byte meterType = encryptedTelegramData.Read<byte>(7 * 8, 8, ByteOrder.BigEndian);
|
|
|
|
description += String.Format(", MT=0x{0:X2}, Status=0x{1:X2}, RSSI=0x{2:X2}, Read=0x{3:X8}, Alarms=0x{4:X2}", meterType, pamStatus, pamRssi, read, alarms);
|
|
|
|
description += ", " + encryptedTelegramData.ToHexString();
|
|
|
|
if (meterType == IPerlS4.MeterType)
|
|
{
|
|
SemiReceived(radioAddress, new IPerlS4Semi(encryptedTelegramData));
|
|
}
|
|
}
|
|
}
|
|
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.Debug)
|
|
{
|
|
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
|
|
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
|
|
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
byte[] plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
UInt16 actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
description = "Debug, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
description = "Debug, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
|
|
}
|
|
|
|
}
|
|
else // Assume unencrypted - Data could be garbage
|
|
{
|
|
description = "Debug (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
|
|
}
|
|
|
|
|
|
}
|
|
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.LOG)
|
|
{
|
|
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
|
|
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
|
|
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
byte[] plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
UInt16 actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
Sensus.Protocols.SensusRF.LOGTelegram logTelegram = Sensus.Protocols.SensusRF.LOGTelegram.Parse(plaintext, 0, (uint)plaintext.Length);
|
|
description = "LOG, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + plaintext.ToHexString();
|
|
description += logTelegram.ToString();
|
|
|
|
LogReceived(radioAddress, logTelegram);
|
|
}
|
|
else
|
|
{
|
|
description = "LOG, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed, " + encryptedTelegramData.ToHexString();
|
|
}
|
|
|
|
}
|
|
else // Assume unencrypted - Data could be garbage
|
|
{
|
|
Sensus.Protocols.SensusRF.LOGTelegram logTelegram = Sensus.Protocols.SensusRF.LOGTelegram.Parse(encryptedTelegramData, 0, (uint)encryptedTelegramData.Length);
|
|
description = "LOG (raw), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + encryptedTelegramData.ToHexString();
|
|
description += logTelegram.ToString();
|
|
|
|
LogReceived(radioAddress, logTelegram);
|
|
}
|
|
}
|
|
|
|
else if (telegramType == Sensus.Protocols.SensusRF.TelegramType.FlexNet)
|
|
{
|
|
// byte DataType; ///< 0x00 for BUP, 0x01 for message
|
|
// union
|
|
// {
|
|
// struct
|
|
// {
|
|
// UInt16 TimeSync; ///<
|
|
// byte FnCount;
|
|
// byte FlexNetFrame[43]; ///< Classic frame including 2 byte sync and CRC
|
|
// } Bup;
|
|
// struct
|
|
// {
|
|
// byte PamStatus; ///<
|
|
// byte Rssi;
|
|
// byte FlexNetFrame[43]; ///< Classic frame including 2 byte sync and CRC
|
|
// } Message;
|
|
// }
|
|
|
|
int encyptPayloadLength = length - 7 /* header */ - 2 /* header CRC */ - 2 /*payload CRC */;
|
|
byte[] encryptedTelegramData = new byte[encyptPayloadLength];
|
|
Array.Copy(payload, (int)appCodeIndex + 8, encryptedTelegramData, 0, encyptPayloadLength);
|
|
UInt16 rawActualCRC = encryptedTelegramData.Read<UInt16>((uint)(encryptedTelegramData.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
UInt16 actualCRC = 0x0000;
|
|
UInt16 expectedCRC = 0xffff;
|
|
byte[] plaintext = new byte[0];
|
|
|
|
byte[] key = SensusRfDecryptKey();
|
|
if (null != key)
|
|
{
|
|
plaintext = Sensus.Protocols.SensusRF.TelegramFrame.Decrypt(radioAddress, counter, encryptedTelegramData, key);
|
|
|
|
actualCRC = plaintext.Read<UInt16>((uint)(plaintext.Length - 2) * 8, 16, ByteOrder.BigEndian);
|
|
expectedCRC = CRC16.SIRT.Calculate(
|
|
(
|
|
length == 0x0d
|
|
? CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
: CRC16.SIRT.Calculate(new byte[] { (byte)((radioAddress >> 16) & 0xFF), (byte)((radioAddress >> 8) & 0xFF), (byte)(radioAddress & 0xFF) })
|
|
),
|
|
plaintext,
|
|
0,
|
|
plaintext.Length - 2
|
|
);
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
byte dataType = plaintext[0];
|
|
|
|
if (dataType == 0)
|
|
{
|
|
// BUP
|
|
UInt16 timeSync = plaintext.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
|
|
byte fnCount = plaintext[3];
|
|
int plaintextLen = plaintext.Length - 4;
|
|
byte[] flexNetFrame = new byte[plaintextLen];
|
|
Array.Copy(plaintext, 4, flexNetFrame, 0, plaintextLen);
|
|
description = "FN-BUP , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
// Message
|
|
byte pamStatus = plaintext[1];
|
|
byte rssi = plaintext[2];
|
|
byte[] flexNetFrame = new byte[43];
|
|
Array.Copy(plaintext, 3, flexNetFrame, 0, 43);
|
|
description = "FN-Msg, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
|
|
|
|
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
|
|
FlexNetReceived(radioAddress, fnMsgFrame);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = "FN, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", Decryption Failed";
|
|
}
|
|
}
|
|
|
|
// CRCs will match if decryption was successful
|
|
if (actualCRC == expectedCRC)
|
|
{
|
|
byte dataType = plaintext[0];
|
|
|
|
if (dataType == 0)
|
|
{
|
|
// BUP
|
|
UInt16 timeSync = plaintext.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
|
|
byte fnCount = plaintext[3];
|
|
int plaintextLen = plaintext.Length - 4;
|
|
byte[] flexNetFrame = new byte[plaintextLen];
|
|
Array.Copy(plaintext, 4, flexNetFrame, 0, plaintextLen);
|
|
description = "FN-BUP , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
// Message
|
|
byte pamStatus = plaintext[1];
|
|
byte rssi = plaintext[2];
|
|
byte[] flexNetFrame = new byte[43];
|
|
Array.Copy(plaintext, 3, flexNetFrame, 0, 43);
|
|
description = "FN-Msg, " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
|
|
|
|
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
|
|
FlexNetReceived(radioAddress, fnMsgFrame);
|
|
}
|
|
}
|
|
else // Assume unencrypted - Data could be garbage
|
|
{
|
|
byte dataType = encryptedTelegramData[0];
|
|
|
|
if (dataType == 0)
|
|
{
|
|
// BUP
|
|
UInt16 timeSync = encryptedTelegramData.Read<UInt16>((1 * 8), 16, ByteOrder.BigEndian);
|
|
byte fnCount = encryptedTelegramData[3];
|
|
int plaintextLen = encryptedTelegramData.Length - 4;
|
|
byte[] flexNetFrame = new byte[plaintextLen];
|
|
Array.Copy(encryptedTelegramData, 4, flexNetFrame, 0, plaintextLen);
|
|
description = "FN-BUP (unencrypted) , " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + timeSync + ", " + fnCount + ", " + flexNetFrame.ToHexString();
|
|
}
|
|
else
|
|
{
|
|
// Message
|
|
byte pamStatus = encryptedTelegramData[1];
|
|
byte rssi = encryptedTelegramData[2];
|
|
byte[] flexNetFrame = new byte[43];
|
|
Array.Copy(encryptedTelegramData, 3, flexNetFrame, 0, 43);
|
|
description = "FN-Msg (unencrypted), " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter + ", " + pamStatus + ", " + rssi + ", " + flexNetFrame.ToHexString();
|
|
|
|
NA2WMessageFrame fnMsgFrame = NA2WMessageFrame.Parse(flexNetFrame, 0);
|
|
FlexNetReceived(radioAddress, fnMsgFrame);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = telegramType.ToString() + ", " + radioAddress + String.Format(" (0x{0:X8})", radioAddress) + ", " + counter;
|
|
}
|
|
}
|
|
else if (serialRadioFrameMessage.RadioFrameType == RadioFrameType.WMBUS)
|
|
{
|
|
// typedef struct
|
|
// {
|
|
// uint8_t L; ///< Length field, does not include CRC bytes... If ((L-9) % 16) != 0 then the last block will contain ((L-9) % 16) bytes of data
|
|
// WMBus_ControlField_t C; ///< Control field
|
|
// WMBus_ManufacturerId_t M; ///< Manufacturer Id field
|
|
// union
|
|
// {
|
|
// struct
|
|
// {
|
|
// uint32_t MeterId; ///< Serial number of the meter
|
|
// uint8_t Version; ///< Meter version number
|
|
// uint8_t DeviceType; ///< Meter device type
|
|
// };
|
|
// uint8_t A[6]; ///< Address field
|
|
// };
|
|
// } WMBus_TBlock1_t;
|
|
|
|
uint block1Offset = 3;
|
|
String packetTypeStr = "T2";
|
|
if (syncWord == (SyncWord)0x543D)
|
|
{
|
|
block1Offset = 2;
|
|
packetTypeStr = "T1";
|
|
}
|
|
|
|
UInt32 meterId = 0;
|
|
UInt32 meterIdRaw = payload.Read<UInt32>((4 + block1Offset) * 8, 32);
|
|
for (int i = 3; i >= 0; i--)
|
|
{
|
|
meterId *= 100;
|
|
meterId += 10 * ((uint)(payload[block1Offset + 4 + i]) >> 4) + ((uint)(payload[block1Offset + 4 + i]) & 0x0f);
|
|
}
|
|
UInt16 manufacturerIdRaw = payload.Read<UInt16>((block1Offset + 2) * 8, 16);
|
|
|
|
byte[] manufacturerIdAscii = new byte[3];
|
|
manufacturerIdAscii[0] = (byte)(((manufacturerIdRaw >> 10) & 0x001F) + 64);
|
|
manufacturerIdAscii[1] = (byte)(((manufacturerIdRaw >> 5) & 0x001F) + 64);
|
|
manufacturerIdAscii[2] = (byte)(((manufacturerIdRaw) & 0x001F) + 64);
|
|
|
|
byte version = payload[block1Offset + 8];
|
|
Utility.WMBusDeviceType deviceType = (Utility.WMBusDeviceType)(payload[block1Offset + 9]);
|
|
|
|
description = "WMBUS, " + packetTypeStr + ", " + String.Format("{0:D8}, (0x{1:X8}), ", meterId, meterIdRaw);
|
|
description += deviceType.ToString() + " - " + manufacturerIdAscii.ToASCIIString() + String.Format(" - 0x{0:X2}", version);
|
|
|
|
channelizedFlexNetId.ID = meterId;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
description = serialRadioFrameMessage.Payload.ToBytes().ToHexString();
|
|
}
|
|
}
|
|
|
|
double temp;
|
|
temp = double.NaN;
|
|
string signal = String.Format("{0:0.0}", temp);
|
|
temp = double.NaN;
|
|
string noise = String.Format("{0:0.0}", temp);
|
|
|
|
bool postReception = true;
|
|
if (windowViewModel.RadioReceiveFilterEnabled)
|
|
{
|
|
ChannelizedFlexNetId filterChannelizedFlexNetId;
|
|
if (ChannelizedFlexNetId.TryParseFlexNetID(windowViewModel.RadioReceiveFilterFnid, out filterChannelizedFlexNetId))
|
|
{
|
|
postReception = ((uint)(channelizedFlexNetId.ID) == (uint)(filterChannelizedFlexNetId.ID));
|
|
}
|
|
}
|
|
|
|
if (postReception)
|
|
{
|
|
ReceivedMessage receivedMessage = new ReceivedMessage()
|
|
{
|
|
TimeStamp = timeStamp,
|
|
Description = description,
|
|
Signal = signal,
|
|
Noise = noise
|
|
};
|
|
|
|
windowViewModel.Add(receivedMessage);
|
|
}
|
|
}
|
|
else if (message.Payload is SerialEventNotification)
|
|
{
|
|
SerialEventNotification serialEventNotification = (SerialEventNotification)message.Payload;
|
|
EventNotification eventNotification = new EventNotification();
|
|
Frame notification = (Frame)(serialEventNotification.Payload);
|
|
byte[] notificationBytes = notification.ToBytes();
|
|
|
|
SByte idNum = notificationBytes.Read<SByte>((0 * 8) + 0, 8);
|
|
UInt64 timeStamp = notificationBytes.Read<UInt64>((1 * 8) + 0, 64);
|
|
UInt16 numDataBytes = notificationBytes.Read<UInt16>((9 * 8) + 0, 16);
|
|
UInt16 fileIdNum = notificationBytes.Read<UInt16>((11 * 8) + 0, 16);
|
|
UInt16 lineNum = notificationBytes.Read<UInt16>((13 * 8) + 0, 16);
|
|
UInt16 eventDataLength = (UInt16)((numDataBytes <= notificationBytes.Length - 15) ? numDataBytes : (notificationBytes.Length - 15));
|
|
byte[] eventData = new byte[eventDataLength];
|
|
Array.Copy(notificationBytes, 15, eventData, 0, eventDataLength);
|
|
|
|
eventNotification.TimeStamp = DateTime.Now.ToLongTimeString(); // String.Format("{0}", timeStamp);
|
|
eventNotification.Data = eventData.ToHexString();
|
|
|
|
GlobalIPerlEvent iPerlEvent = new GlobalIPerlEvent(idNum, eventData, fileIdNum, lineNum);
|
|
eventNotification.Id = iPerlEvent.Name;
|
|
eventNotification.File = iPerlEvent.File;
|
|
eventNotification.Line = fileIdNum.ToString();
|
|
eventNotification.Description = iPerlEvent.Description;
|
|
|
|
windowViewModel.Add(eventNotification);
|
|
}
|
|
else if (message.Payload is FactoryTestCommandComplete)
|
|
{
|
|
FactoryTestCommandComplete ftcComplete = (FactoryTestCommandComplete)message.Payload;
|
|
|
|
if (ftcComplete.TestCommand == 0x06)
|
|
{
|
|
// Sample RF Signal - additional data is 2 byte signal value in 10th dBm
|
|
byte[] data = ftcComplete.AdditionalData;
|
|
if (data.Length > 1)
|
|
{
|
|
Int16 signalLevel = data.Read<Int16>(0, 16);
|
|
double temp;
|
|
temp = ((double)(signalLevel) / 10);
|
|
string raw = String.Format("{0:0.0}", temp);
|
|
|
|
signalLevel = data.Read<Int16>(16, 16);
|
|
temp = ((double)(signalLevel) / 10);
|
|
string signalCw = String.Format("{0:0.0}", temp);
|
|
|
|
signalLevel = data.Read<Int16>(32, 16);
|
|
temp = ((double)(signalLevel) / 10);
|
|
string signalMod = String.Format("{0:0.0}", temp);
|
|
|
|
string timeStamp = DateTime.Now.ToLongTimeString();
|
|
|
|
ReceivedMessage receivedMessage = new ReceivedMessage()
|
|
{
|
|
TimeStamp = timeStamp,
|
|
Description = "RSSI" + " (" + raw + ", " + signalCw + ")",
|
|
Signal = signalMod,
|
|
Noise = ""
|
|
};
|
|
|
|
windowViewModel.Add(receivedMessage);
|
|
}
|
|
}
|
|
else if (ftcComplete.TestCommand == 0x07)
|
|
{
|
|
UInt32 testCount = (UInt32)(
|
|
ftcComplete.AdditionalData[0] << 0
|
|
| ftcComplete.AdditionalData[1] << 8
|
|
| ftcComplete.AdditionalData[2] << 16
|
|
| ftcComplete.AdditionalData[3] << 24
|
|
);
|
|
Utility.Log.Write($"Frequency Count Test Result: {testCount:N0} Hz\n");
|
|
windowViewModel.Test32kHzResult = testCount.ToString("N0") + " Hz";
|
|
}
|
|
}
|
|
else if (message.Payload is CommandErrorResponse)
|
|
{
|
|
CommandErrorResponse commandErrorResponse = (CommandErrorResponse)message.Payload;
|
|
LogError("Error Code: " + String.Format("{0:X2}", commandErrorResponse.ErrorCode));
|
|
}
|
|
else if (message.Payload is MemoryDataResponse)
|
|
{
|
|
MemoryDataResponse memoryDataResponse = (MemoryDataResponse)message.Payload;
|
|
byte[] data = memoryDataResponse.Data;
|
|
int numberOfBytes = data.Length;
|
|
String dataString = "";
|
|
uint address = memoryDataResponse.Address;
|
|
|
|
uint index = 0;
|
|
while (numberOfBytes > 16)
|
|
{
|
|
byte[] lineData = data.Read<byte[]>(index * 8, 16 * 8);
|
|
|
|
dataString += (memoryDataResponse.Source == 0 ? "P" : "F") + String.Format(" 0x{0:X8}: ", address) + lineData.ToHexString() + System.Environment.NewLine;
|
|
|
|
index += 16;
|
|
address += 16;
|
|
numberOfBytes -= 16;
|
|
}
|
|
|
|
if (numberOfBytes > 0)
|
|
{
|
|
byte[] lineData = data.Read<byte[]>(index * 8, (uint)(8 * numberOfBytes));
|
|
|
|
dataString += (memoryDataResponse.Source == 0 ? "P" : "F") + String.Format(" 0x{0:X8}: ", address) + lineData.ToHexString() + System.Environment.NewLine;
|
|
}
|
|
|
|
windowViewModel.MemoryReadData += dataString;
|
|
}
|
|
}
|
|
|
|
|
|
private byte[] SensusRfKey()
|
|
{
|
|
|
|
return windowViewModel.KeyManager.GetKey(windowViewModel.SRfKeySelectedItem);
|
|
//if (windowViewModel.SRfKeySelectedItem == "Anglian")
|
|
//{
|
|
// return AnglianKey.Value;
|
|
//}
|
|
//else
|
|
//{
|
|
// return ThamesKey.Value;
|
|
//}
|
|
}
|
|
|
|
private byte[] SensusRfDecryptKey()
|
|
{
|
|
return SensusRfKey();
|
|
}
|
|
|
|
public void BupReceived(UInt32 address, IFrame frame)
|
|
{
|
|
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.ActivityBup, address, frame);
|
|
|
|
receiveQueue.Enqueue(e);
|
|
}
|
|
|
|
public void SemiReceived(UInt32 address, IFrame frame)
|
|
{
|
|
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.Semi, address, frame);
|
|
|
|
receiveQueue.Enqueue(e);
|
|
}
|
|
|
|
public void LogReceived(UInt32 address, IFrame frame)
|
|
{
|
|
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.Log, address, frame);
|
|
|
|
receiveQueue.Enqueue(e);
|
|
}
|
|
|
|
public void FlexNetReceived(UInt32 address, IFrame frame)
|
|
{
|
|
FrameEventArgs<IFrame> e = new FrameEventArgs<IFrame>(FrameEvent.FlexNetFrame, address, frame);
|
|
|
|
receiveQueue.Enqueue(e);
|
|
}
|
|
|
|
public void MessageReceived(FrameEventArgs<IFrame> e)
|
|
{
|
|
receiveQueue.Enqueue(e);
|
|
}
|
|
|
|
public event EventHandler<FrameEventArgs<IFrame>> FrameReceived;
|
|
|
|
private void FrameEventLoop()
|
|
{
|
|
while (true)
|
|
{
|
|
var newMessage = receiveQueue.Dequeue().Cast<IFrame>();
|
|
|
|
if (newMessage.FrameEvent == FrameEvent.Log)
|
|
{
|
|
DumpLog(newMessage.Address, newMessage.Frame);
|
|
}
|
|
|
|
try
|
|
{
|
|
FrameReceived.Raise(this, newMessage);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.Log.Write("Exception trying to notify of received frame: " + ex.ToString() + Environment.NewLine);
|
|
}
|
|
}
|
|
}
|
|
|
|
private Thread eventThread;
|
|
private BlockingQueue<FrameEventArgs<IFrame>> receiveQueue;
|
|
|
|
#if false
|
|
private string PomCollectionItemToName(Collection<PomComboBoxItem> collection, string value)
|
|
{
|
|
string name = "Unknown: " + value;
|
|
|
|
PomComboBoxItem item = collection.Where(i => i.Value == value).FirstOrDefault();
|
|
if (null != item)
|
|
{
|
|
name = item.Name;
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
private string PomCollectionItemToName(Collection<PomComboBoxItem> collection, byte value)
|
|
{
|
|
string valueString = String.Format("{0}", value);
|
|
return PomCollectionItemToName(collection, valueString);
|
|
}
|
|
#endif
|
|
|
|
private void DumpLog(UInt32 address, IFrame logFrame)
|
|
{
|
|
Utility.Log.Write(logFrame.ToString() + System.Environment.NewLine);
|
|
}
|
|
|
|
public ClassicSerialMessageFrame SendFlexNetSerial(ISerialCommand cmd, bool responseExpected, UInt32 timeoutMs)
|
|
{
|
|
ClassicSerialCommandFrame cmdFrame = new ClassicSerialCommandFrame(0x00, cmd);
|
|
cmdFrame.Bake();
|
|
|
|
LogOutgoing(cmdFrame);
|
|
|
|
return serialManager.SendFlexNetSerial(cmdFrame, responseExpected, timeoutMs);
|
|
}
|
|
|
|
public ClassicSerialMessageFrame SendFlexNetSerial(ISerialCommand cmd, bool responseExpected)
|
|
{
|
|
return SendFlexNetSerial(cmd, responseExpected, 3000);
|
|
}
|
|
|
|
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, bool responseExpected, UInt32 timeoutMs)
|
|
{
|
|
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
|
|
cmdFrame.Bake();
|
|
|
|
LogOutgoing(cmdFrame);
|
|
|
|
return serialManager.SendNa2wSerial(cmdFrame, responseExpected, timeoutMs);
|
|
}
|
|
|
|
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, bool responseExpected)
|
|
{
|
|
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
|
|
cmdFrame.Bake();
|
|
|
|
LogOutgoing(cmdFrame);
|
|
|
|
return serialManager.SendNa2wSerial(cmdFrame, responseExpected);
|
|
}
|
|
|
|
public NA2WSerialFrame SendNa2wSerial(IFrame frame, bool responseExpected)
|
|
{
|
|
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(frame);
|
|
|
|
// set the radio frame type if this is a FNV2 radio frame
|
|
if ( (frame is Frame)
|
|
&& (0xAC == (frame as Frame)[0])
|
|
&& (0xC5 == (frame as Frame)[1])
|
|
&& (cmdFrame.Payload is NetworkMessage)
|
|
&& ((cmdFrame.Payload as NetworkMessage).Payload is SerialRadioFrameMessage)
|
|
)
|
|
{
|
|
((cmdFrame.Payload as NetworkMessage).Payload as SerialRadioFrameMessage).RadioFrameType = RadioFrameType.FlexNetV2;
|
|
}
|
|
|
|
cmdFrame.Bake();
|
|
|
|
LogOutgoing(cmdFrame);
|
|
|
|
return serialManager.SendNa2wSerial(cmdFrame, responseExpected);
|
|
}
|
|
|
|
public NA2WSerialFrame SendNa2wSerial(ISerialCommand cmd, byte responseCommandCode)
|
|
{
|
|
NA2WSerialFrame cmdFrame = new NA2WSerialFrame(cmd);
|
|
cmdFrame.Bake();
|
|
|
|
LogOutgoing(cmdFrame);
|
|
|
|
return serialManager.SendNa2wSerial(cmdFrame, responseCommandCode);
|
|
}
|
|
|
|
public void SendNa2wSerial(ISerialMessage msg)
|
|
{
|
|
NA2WSerialFrame msgFrame = new NA2WSerialFrame(msg);
|
|
msgFrame.Bake();
|
|
|
|
LogOutgoing(msgFrame);
|
|
|
|
serialManager.SendNa2wSerial(msgFrame, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The format string used for time stamps. Default is"yyyy-MM-dd HH:mm:ss.fffzz" which is
|
|
/// the Sensus standard logging date format.
|
|
/// </summary>
|
|
public static string TimeFormatString = "yyyy-MM-dd HH:mm:ss.fffzz";
|
|
|
|
void LogIncoming(ISerialMessageFrame message)
|
|
{
|
|
if (windowViewModel.LogWithDescription)
|
|
{
|
|
String messageType = message.Payload.GetType().ToString();
|
|
String messageName = messageType.Substring(messageType.LastIndexOf('.') + 1);
|
|
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " < " + messageName + "\n");
|
|
}
|
|
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " < " + message.ToHexString() + "\n");
|
|
if (windowViewModel.LogWithDetails) Utility.Log.Write(message.ToString() + "\n");
|
|
}
|
|
|
|
void LogOutgoing(ClassicSerialCommandFrame command)
|
|
{
|
|
if (windowViewModel.LogClearOnCommand) Log.Clear();
|
|
if (windowViewModel.LogWithDescription)
|
|
{
|
|
String commandType = command.Payload.GetType().ToString();
|
|
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
|
|
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
|
|
}
|
|
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + command.ToHexString() + "\n");
|
|
if (windowViewModel.LogWithDetails) Utility.Log.Write(command.ToString() + "\n");
|
|
}
|
|
|
|
void LogOutgoing(NA2WSerialFrame command)
|
|
{
|
|
if (windowViewModel.LogClearOnCommand) Log.Clear();
|
|
if (windowViewModel.LogWithDescription)
|
|
{
|
|
if (command.Payload is NetworkCommand)
|
|
{
|
|
NetworkCommand networkCommand = (NetworkCommand)command.Payload;
|
|
String commandType = networkCommand.Payload.GetType().ToString();
|
|
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
|
|
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
|
|
}
|
|
else if (command.Payload is NetworkMessage)
|
|
{
|
|
NetworkMessage networkMessage = (NetworkMessage)command.Payload;
|
|
String commandType = networkMessage.Payload.GetType().ToString();
|
|
String commandName = commandType.Substring(commandType.LastIndexOf('.') + 1);
|
|
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + commandName + "\n");
|
|
|
|
}
|
|
|
|
}
|
|
if (windowViewModel.LogWithHexString) Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " > " + command.ToHexString() + "\n");
|
|
if (windowViewModel.LogWithDetails) Utility.Log.Write(command.ToString() + "\n");
|
|
}
|
|
|
|
void LogError(String error)
|
|
{
|
|
if (windowViewModel.LogWithDescription)
|
|
{
|
|
Utility.Log.Write(DateTime.Now.ToString(TimeFormatString) + " - " + error + "\n");
|
|
}
|
|
}
|
|
|
|
|
|
private void SetComPortList(String[] list)
|
|
{
|
|
ObservableCollection<String> comPortObservableCollection = new ObservableCollection<String>();
|
|
|
|
foreach (String s in list)
|
|
{
|
|
comPortObservableCollection.Add(s);
|
|
}
|
|
|
|
// Set collection
|
|
windowViewModel.ComPortObservableCollection = comPortObservableCollection;
|
|
|
|
// Default to first item in collection
|
|
if (list.Length > 0)
|
|
{
|
|
windowViewModel.ComPortSelectedItem = list[0];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Static member function that returns a sorted string array of all the
|
|
/// COM port names found in the system.
|
|
/// </summary>
|
|
/// <returns>{"COM1","COM7",...,"COM40",...,COMn}</returns>
|
|
private string[] GetPortNames()
|
|
|
|
{
|
|
string[] ports = Sensus.COMUtils.GetPortNames().ToArray();
|
|
Array.Sort(ports, new ComCompare());
|
|
return ports;
|
|
}
|
|
|
|
public void SaveDefaultConfigurationValues()
|
|
{
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId = windowViewModel.DeviceIdNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber = windowViewModel.SerialNumberNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote = windowViewModel.ManufacturingNoteNew;
|
|
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_TemperatureCalOffset = windowViewModel.TemperatureCalOffsetNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalOffset = windowViewModel.VbatCalOffsetNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalSlope = windowViewModel.VbatCalSlopeNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalOffset = windowViewModel.VsysCalOffsetNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalSlope = windowViewModel.VsysCalSlopeNew;
|
|
|
|
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_TcxoCorrection = windowViewModel.TcxoCorrectionNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_PaOffPowerLevel = windowViewModel.RfPowerLevelNew;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Configuration_ButtonPressAction = windowViewModel.ButtonPressAction;
|
|
}
|
|
|
|
public void LoadDefaultConfigurationValues()
|
|
{
|
|
windowViewModel.DeviceIdNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_DeviceId;
|
|
windowViewModel.SerialNumberNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_SerialNumber;
|
|
windowViewModel.ManufacturingNoteNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_ManufacturingNote;
|
|
|
|
windowViewModel.TemperatureCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_TemperatureCalOffset;
|
|
windowViewModel.VbatCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalOffset;
|
|
windowViewModel.VbatCalSlopeNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VbatCalSlope;
|
|
windowViewModel.VsysCalOffsetNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalOffset;
|
|
windowViewModel.VsysCalSlopeNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_VsysCalSlope;
|
|
|
|
windowViewModel.TcxoCorrectionNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_TcxoCorrection;
|
|
windowViewModel.RfPowerLevelNew = GlobalIPerlUtility.Properties.Settings.Default.Configuration_PaOffPowerLevel;
|
|
|
|
windowViewModel.ButtonPressAction = GlobalIPerlUtility.Properties.Settings.Default.Configuration_ButtonPressAction;
|
|
}
|
|
|
|
public void SaveDefaultCommandValues()
|
|
{
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngFrequency = windowViewModel.TxEng_Frequency;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngDuration = windowViewModel.TxEng_Duration;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngTransceiverPower = windowViewModel.TxEng_TransceiverPower;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngModulation = windowViewModel.TxEng_Modulation;
|
|
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxFrequency = windowViewModel.Tx_Frequency;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxDuration = windowViewModel.Tx_Duration;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_TxModulation = windowViewModel.Tx_Modulation;
|
|
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_RxFrequency = windowViewModel.Rx_Frequency;
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_RxModulation = windowViewModel.Rx_Modulation;
|
|
|
|
GlobalIPerlUtility.Properties.Settings.Default.Command_RxSensitivity = windowViewModel.Rx_Sensitivity;
|
|
}
|
|
|
|
public void LoadDefaultCommandValues()
|
|
{
|
|
windowViewModel.TxEng_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngFrequency;
|
|
windowViewModel.TxEng_Duration = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngDuration;
|
|
windowViewModel.TxEng_TransceiverPower = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngTransceiverPower;
|
|
windowViewModel.TxEng_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_TxEngModulation;
|
|
|
|
windowViewModel.Tx_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_TxFrequency;
|
|
windowViewModel.Tx_Duration = GlobalIPerlUtility.Properties.Settings.Default.Command_TxDuration;
|
|
windowViewModel.Tx_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_TxModulation;
|
|
|
|
windowViewModel.Rx_Frequency = GlobalIPerlUtility.Properties.Settings.Default.Command_RxFrequency;
|
|
windowViewModel.Rx_Modulation = GlobalIPerlUtility.Properties.Settings.Default.Command_RxModulation;
|
|
|
|
windowViewModel.Rx_Sensitivity = GlobalIPerlUtility.Properties.Settings.Default.Command_RxSensitivity;
|
|
}
|
|
|
|
public void FwdlTaskProgressCallback(Object task, Double percentDone, String statusString)
|
|
{
|
|
windowViewModel.UpgradePercent = percentDone;
|
|
|
|
if (statusString != null)
|
|
{
|
|
windowViewModel.UpgradeStatus = statusString;
|
|
}
|
|
}
|
|
|
|
public void FwdlTaskCompletionCallback(Object task, bool successfullyCompleted)
|
|
{
|
|
windowViewModel.UpgradeActive = false;
|
|
|
|
_serialFirmwareDownloadTask = null;
|
|
}
|
|
|
|
private SerialFirmwareDownloadTask _serialFirmwareDownloadTask = null;
|
|
public void FwdlCommand(string type)
|
|
{
|
|
if (type.Equals("Start"))
|
|
{
|
|
_serialFirmwareDownloadTask = new SerialFirmwareDownloadTask(windowViewModel.UpgradeFileName, this, (ushort)(serialManager is MeterTestHatLink ? 8 : 10));
|
|
_serialFirmwareDownloadTask.TaskProgressCallback = FwdlTaskProgressCallback;
|
|
|
|
windowViewModel.UpgradeActive = true;
|
|
|
|
_serialFirmwareDownloadTask.Start(FwdlTaskCompletionCallback);
|
|
}
|
|
else if (type.Equals("Stop"))
|
|
{
|
|
if (_serialFirmwareDownloadTask != null)
|
|
{
|
|
_serialFirmwareDownloadTask.Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void EventLogTaskProgressCallback(Object task, Double percentDone, String statusString)
|
|
{
|
|
if (statusString != null)
|
|
{
|
|
windowViewModel.EventLogStatus = statusString;
|
|
}
|
|
}
|
|
|
|
public void EventLogTaskCompletionCallback(Object task, bool successfullyCompleted)
|
|
{
|
|
windowViewModel.EventLogActive = false;
|
|
|
|
_eventLogTask = null;
|
|
}
|
|
|
|
public void EventLogTaskLogCallback(Object task, EventNotification eventNotification)
|
|
{
|
|
windowViewModel.AddToEventLog(eventNotification);
|
|
}
|
|
|
|
|
|
private EventLogTask _eventLogTask = null;
|
|
public void EventLogCommand(string type)
|
|
{
|
|
if (type.Equals("Start"))
|
|
{
|
|
String timeFrameString = windowViewModel.EventLogTimeFrameSelectedValue;
|
|
UInt32 timeFrameSec = 0xffffffff;
|
|
if (!string.IsNullOrEmpty(timeFrameString))
|
|
{
|
|
if (timeFrameString.Equals("Last Hour"))
|
|
{
|
|
timeFrameSec = 60 * 60;
|
|
}
|
|
else if (timeFrameString.Equals("Last Day"))
|
|
{
|
|
timeFrameSec = 60 * 60 * 24;
|
|
}
|
|
else if (timeFrameString.Equals("Last Week"))
|
|
{
|
|
timeFrameSec = 60 * 60 * 24 * 7;
|
|
}
|
|
else if (timeFrameString.Equals("Last 30 Days"))
|
|
{
|
|
timeFrameSec = 60 * 60 * 24 * 7 * 30;
|
|
}
|
|
}
|
|
|
|
windowViewModel.EventLogActive = true;
|
|
windowViewModel.ClearEventLog();
|
|
|
|
_eventLogTask = new EventLogTask(this);
|
|
_eventLogTask.TaskProgressCallback = EventLogTaskProgressCallback;
|
|
_eventLogTask.TaskLogCallback = EventLogTaskLogCallback;
|
|
_eventLogTask.TimeFrame = timeFrameSec;
|
|
_eventLogTask.Start(EventLogTaskCompletionCallback);
|
|
}
|
|
else if (type.Equals("Stop"))
|
|
{
|
|
if (_eventLogTask != null)
|
|
{
|
|
_eventLogTask.Stop();
|
|
}
|
|
}
|
|
else if (type.Equals("Export"))
|
|
{
|
|
String fileName = EventLogToCsv(null);
|
|
|
|
if (fileName != null)
|
|
{
|
|
windowViewModel.EventLogStatus = "Exported to " + fileName;
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.EventLogStatus = "Error trying to export";
|
|
}
|
|
}
|
|
}
|
|
|
|
public string EventLogToCsv(string folder)
|
|
{
|
|
string separator = ",";
|
|
StringBuilder builder = new StringBuilder(Convert.ToString((char)65279));
|
|
|
|
ObservableCollection<EventNotification> eventNotificationCollection = windowViewModel.EventLogCollection;
|
|
|
|
// Build header
|
|
List<string> tempList = new List<string>();
|
|
tempList.Add("Event");
|
|
tempList.Add("Time Stamp");
|
|
tempList.Add("Description");
|
|
tempList.Add("Raw Data");
|
|
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
|
|
|
|
// Populate data
|
|
for (int i = 0; i < eventNotificationCollection.Count; i++)
|
|
{
|
|
tempList = new List<string>();
|
|
tempList.Add("\"" + eventNotificationCollection[i].Id + "\"");
|
|
tempList.Add(eventNotificationCollection[i].TimeStamp);
|
|
tempList.Add("\"" + eventNotificationCollection[i].Description + "\"");
|
|
tempList.Add(eventNotificationCollection[i].Data);
|
|
|
|
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
|
|
}
|
|
builder.ToString();
|
|
|
|
// Save to CSV
|
|
try
|
|
{
|
|
string destination = "cl" + windowViewModel.SerialNumber + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_event_log";
|
|
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
|
|
{
|
|
destination = destination.Replace(c, '_');
|
|
}
|
|
if (string.IsNullOrEmpty(folder))
|
|
{
|
|
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
|
}
|
|
destination = folder + "\\" + destination + ".csv";
|
|
FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write);
|
|
StreamWriter objWrite = new StreamWriter(fs);
|
|
objWrite.Write(builder);
|
|
objWrite.Close();
|
|
|
|
return destination;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void StatsLogTaskProgressCallback(Object task, Double percentDone, String statusString)
|
|
{
|
|
if (statusString != null)
|
|
{
|
|
windowViewModel.StatsLogStatus = statusString;
|
|
}
|
|
}
|
|
|
|
public void StatsLogTaskCompletionCallback(Object task, bool successfullyCompleted)
|
|
{
|
|
windowViewModel.StatsLogActive = false;
|
|
|
|
_statsLogTask = null;
|
|
}
|
|
|
|
public void StatsLogTaskLogCallback(Object task, StatisticsEntry statisticsEntry)
|
|
{
|
|
windowViewModel.AddToStatsLog(statisticsEntry);
|
|
}
|
|
|
|
private StatsLogTask _statsLogTask = null;
|
|
|
|
public void StatsLogCommand(string type)
|
|
{
|
|
if (type.Equals("Start"))
|
|
{
|
|
windowViewModel.StatsLogActive = true;
|
|
windowViewModel.ClearStatsLog();
|
|
|
|
_statsLogTask = new StatsLogTask(this);
|
|
_statsLogTask.TaskProgressCallback = StatsLogTaskProgressCallback;
|
|
_statsLogTask.TaskLogCallback = StatsLogTaskLogCallback;
|
|
_statsLogTask.Start(StatsLogTaskCompletionCallback);
|
|
}
|
|
else if (type.Equals("Stop"))
|
|
{
|
|
if (_statsLogTask != null)
|
|
{
|
|
_statsLogTask.Stop();
|
|
}
|
|
}
|
|
else if (type.Equals("Export"))
|
|
{
|
|
String fileName = StatsLogToCsv(null);
|
|
|
|
if (fileName != null)
|
|
{
|
|
windowViewModel.StatsLogStatus = "Exported to " + fileName;
|
|
}
|
|
else
|
|
{
|
|
windowViewModel.StatsLogStatus = "Error trying to export";
|
|
}
|
|
}
|
|
}
|
|
|
|
public string StatsLogToCsv(string folder)
|
|
{
|
|
string separator = ",";
|
|
StringBuilder builder = new StringBuilder(Convert.ToString((char)65279));
|
|
|
|
ObservableCollection<StatisticsEntry> statsNotificationCollection = windowViewModel.StatsLogCollection;
|
|
|
|
// Build header
|
|
List<string> tempList = new List<string>();
|
|
tempList.Add("Module");
|
|
tempList.Add("Revision");
|
|
tempList.Add("Data");
|
|
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
|
|
|
|
// Populate data
|
|
for (int i = 0; i < statsNotificationCollection.Count; i++)
|
|
{
|
|
tempList = new List<string>();
|
|
tempList.Add("\"" + statsNotificationCollection[i].Id + "\"");
|
|
tempList.Add(statsNotificationCollection[i].Revision);
|
|
tempList.Add(statsNotificationCollection[i].Data);
|
|
|
|
builder.Append(string.Join(separator, tempList)).Append(Environment.NewLine);
|
|
}
|
|
|
|
// Save to CSV
|
|
try
|
|
{
|
|
string destination = "gi_" + windowViewModel.SerialNumber + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_stats";
|
|
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
|
|
{
|
|
destination = destination.Replace(c, '_');
|
|
}
|
|
if (string.IsNullOrEmpty(folder))
|
|
{
|
|
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
|
}
|
|
destination = folder + "\\" + destination + ".csv";
|
|
FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write);
|
|
StreamWriter objWrite = new StreamWriter(fs);
|
|
objWrite.Write(builder);
|
|
objWrite.Close();
|
|
|
|
return destination;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.Log.Write($"\n\n!!!!!!\n{ex.Message}\n{ex.StackTrace}\n!!!!!!\n\n");
|
|
return null;
|
|
}
|
|
}
|
|
public string TagsToCsv(string folder)
|
|
{
|
|
try
|
|
{
|
|
string destination = "gi_" + windowViewModel.DeviceId + "_" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "_tags";
|
|
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
|
|
{
|
|
destination = destination.Replace(c, '_');
|
|
}
|
|
if (string.IsNullOrEmpty(folder))
|
|
{
|
|
folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
|
}
|
|
destination = folder + "\\" + destination + ".json";
|
|
var options = new JsonSerializerOptions { WriteIndented = true };
|
|
string jsonString = JsonSerializer.Serialize(windowViewModel, options);
|
|
File.WriteAllText(destination, jsonString);
|
|
return destination;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.Log.Write($"\n\n!!!!!!\n{ex.Message}\n{ex.StackTrace}\n!!!!!!\n\n");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void ReadAllTagsTask()
|
|
{
|
|
List<byte> tagReadList = new List<byte>();
|
|
ParameterReadCommand parameterReadCommand;
|
|
|
|
foreach (GlobalIPerlTag value in System.Enum.GetValues(typeof(GlobalIPerlTag)))
|
|
{
|
|
tagReadList.Add((byte)value);
|
|
|
|
if (tagReadList.Count == 5)
|
|
{
|
|
parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
|
|
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
|
|
if (response != null)
|
|
{
|
|
// Have to parse because we awaited for it
|
|
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
|
|
}
|
|
tagReadList = new List<byte>();
|
|
}
|
|
}
|
|
|
|
if (tagReadList.Count != 0)
|
|
{
|
|
parameterReadCommand = new ParameterReadCommand(TagMap.GlobalIPerl, tagReadList);
|
|
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
|
|
if (response != null)
|
|
{
|
|
// Have to parse because we awaited for it
|
|
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
|
|
}
|
|
}
|
|
|
|
foreach (SterlingMetrologyTag value in System.Enum.GetValues(typeof(SterlingMetrologyTag)))
|
|
{
|
|
tagReadList.Add((byte)value);
|
|
|
|
if (tagReadList.Count == 5)
|
|
{
|
|
parameterReadCommand = new ParameterReadCommand((TagMap)0x05, tagReadList);
|
|
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
|
|
if (response != null)
|
|
{
|
|
// Have to parse because we awaited for it
|
|
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
|
|
}
|
|
tagReadList = new List<byte>();
|
|
}
|
|
}
|
|
|
|
if (tagReadList.Count != 0)
|
|
{
|
|
parameterReadCommand = new ParameterReadCommand((TagMap)0x05, tagReadList);
|
|
NA2WSerialFrame response = SendNa2wSerial(parameterReadCommand, ParameterReadResponse._Code); // Wait for response (ParameterRead data) and parse.
|
|
if (response != null)
|
|
{
|
|
// Have to parse because we awaited for it
|
|
MessageReceived(this, new ReceptionEventArgs<ISerialMessageFrame>(response));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ReadAllTags()
|
|
{
|
|
System.Threading.Tasks.Task readAllTagsTask = new System.Threading.Tasks.Task(ReadAllTagsTask);
|
|
readAllTagsTask.Start();
|
|
}
|
|
|
|
public void DiagTaskProgressCallback(Object task, Double percentDone, String statusString)
|
|
{
|
|
if (statusString != null)
|
|
{
|
|
windowViewModel.DiagStatus = statusString;
|
|
}
|
|
}
|
|
|
|
public void DiagTaskCompletionCallback(Object task, bool successfullyCompleted)
|
|
{
|
|
windowViewModel.DiagActive = false;
|
|
|
|
_diagTask = null;
|
|
}
|
|
|
|
public void DiagTaskLogCallback(Object task, EventNotification eventNotification)
|
|
{
|
|
// TBD:
|
|
}
|
|
|
|
private DiagTask _diagTask = null;
|
|
|
|
private void SaveDiagnostics(string outputFile, string mapFile)
|
|
{
|
|
windowViewModel.DiagActive = true;
|
|
|
|
_diagTask = new DiagTask(this);
|
|
_diagTask.TaskProgressCallback = DiagTaskProgressCallback;
|
|
_diagTask.TaskLogCallback = DiagTaskLogCallback;
|
|
_diagTask.Start(DiagTaskCompletionCallback);
|
|
_diagTask.OutputFile = outputFile;
|
|
_diagTask.MapFile = mapFile;
|
|
_diagTask.ViewModel = windowViewModel;
|
|
_diagTask.Start(DiagTaskCompletionCallback);
|
|
}
|
|
} // end class
|
|
|
|
public partial class Ping_Normal : Sensus.Protocols.FlexNet.Ping
|
|
{
|
|
public Ping_Normal()
|
|
: base()
|
|
{
|
|
PingType = PingType.Normal;
|
|
Init();
|
|
}
|
|
|
|
partial void Init();
|
|
|
|
public static new Ping_Normal Parse(byte[] buffer, uint offset)
|
|
{
|
|
return Command.Parse<Ping_Normal>(buffer, offset, CommandLength);
|
|
}
|
|
}
|
|
|
|
public enum FrameEvent
|
|
{
|
|
Undefined,
|
|
ActivityBup,
|
|
Semi,
|
|
Log,
|
|
FlexNetFrame
|
|
}
|
|
|
|
public class FrameEventArgs<TFrame> : EventArgs where TFrame : IFrame
|
|
{
|
|
public FrameEventArgs()
|
|
: this(default(TFrame))
|
|
{
|
|
}
|
|
|
|
public FrameEventArgs(TFrame rxFrame)
|
|
: this(FrameEvent.Undefined, 0, rxFrame)
|
|
{
|
|
}
|
|
|
|
public FrameEventArgs(UInt32 address, TFrame rxFrame)
|
|
: this(FrameEvent.Undefined, address, rxFrame)
|
|
{
|
|
}
|
|
|
|
|
|
public FrameEventArgs(FrameEvent frameEvent, UInt32 address, TFrame rxFrame)
|
|
: base()
|
|
{
|
|
FrameEvent = frameEvent;
|
|
Address = address;
|
|
Frame = rxFrame;
|
|
Timestamp = RelativeTime.Now;
|
|
}
|
|
|
|
//
|
|
// Summary:
|
|
// Event type
|
|
public FrameEvent FrameEvent { get; set; }
|
|
//
|
|
// Summary:
|
|
// Time that the frame was received.
|
|
public RelativeTime Timestamp { get; set; }
|
|
//
|
|
// Summary:
|
|
// Frame received by the communication device.
|
|
public TFrame Frame { get; set; }
|
|
//
|
|
/// <summary>
|
|
/// Address frame targets
|
|
public UInt32 Address { get; set; }
|
|
|
|
public FrameEventArgs<TNewFrame> Cast<TNewFrame>() where TNewFrame : TFrame
|
|
{
|
|
return new FrameEventArgs<TNewFrame>() { FrameEvent = FrameEvent, Timestamp = Timestamp, Frame = (TNewFrame)Frame, Address = Address };
|
|
}
|
|
}
|
|
}
|