Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf41a26a0a | ||
|
|
2e4741b929 | ||
|
|
18cef617da | ||
|
|
4ee736cff5 | ||
|
|
4e40dc8601 | ||
|
|
a5a68ec457 | ||
|
|
e26d88d437 | ||
|
|
2522d1da9f | ||
|
|
8983c01591 | ||
|
|
61b1320d4f | ||
|
|
2c8a0922d1 | ||
|
|
b078d9586d | ||
|
|
6e35de5f4d | ||
|
|
2dbe4cded4 | ||
|
|
10865c6878 | ||
|
|
ee1353fe54 | ||
|
|
5cefd7fc3a | ||
|
|
ab0e5ea82a | ||
|
|
b2276c086c | ||
|
|
0c41c750e8 |
@@ -13,5 +13,6 @@ namespace SchematicDrawing
|
||||
Common.Unit MsrdUnit { get; }
|
||||
double MsrdValLimLo { get; }
|
||||
double MsrdValLimHi { get; }
|
||||
bool IsOffline { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,7 +672,11 @@ namespace SchematicDrawing
|
||||
SizeF size = e.Graphics.MeasureString(strVal, measuredValueFont);
|
||||
Rectangle rect = new Rectangle(itm.X + itm.MsrdX, itm.Y + itm.MsrdY, (int)Math.Round(size.Width) + 4, (int)Math.Round(size.Height) + 2);
|
||||
ItemElementRectangles.Add(new ItemElementRect(item, Element.MeasuredVal, rect));
|
||||
if (measuredValues[msrdValIx] >= itm.MsrdValLimLo && measuredValues[msrdValIx] <= itm.MsrdValLimHi)
|
||||
if ((item as IDrawingItemWithMeasuredVal).IsOffline)
|
||||
{
|
||||
e.Graphics.FillRectangle(measuredValueErrorBackColor, rect);
|
||||
}
|
||||
else if (measuredValues[msrdValIx] >= itm.MsrdValLimLo && measuredValues[msrdValIx] <= itm.MsrdValLimHi)
|
||||
{
|
||||
e.Graphics.FillRectangle(measuredValueBackColor, rect);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Sensus")]
|
||||
[assembly: AssemblyProduct("TestBenchFramework")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013 - 2023 Sensus Slovensko, a.s.")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013 - 2025 Sensus Slovensko, a.s.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.9.2149.4")]
|
||||
[assembly: AssemblyFileVersion("3.9.2149.4")]
|
||||
[assembly: AssemblyVersion("3.9.3013.1")]
|
||||
[assembly: AssemblyFileVersion("3.9.3013.1")]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Version History
|
||||
|
||||
| Version | Target Environment | Title | Description |
|
||||
|------------|--------------------------------------------------------------|-----------------------------------------------------|------------------------------------|
|
||||
| 3.9.2149.0 | HeatMeters, Heat meter sensors, Procedure Dilog, Tab Process | Excanged columns value 'Sensor' and 'Heat meter sensor' | Fix in code ProcedureDlg, row 1851 |
|
||||
| Version | Source of change | Target Environment | Title | Description |
|
||||
|------------|----------------------|--------------------------------------------------------------|-----------------------------------------------------|------------------------------------|
|
||||
| 3.9.2149.0 | Michal databse error | HeatMeters, Heat meter sensors, Procedure Dilog, Tab Process | Excanged columns value 'Sensor' and 'Heat meter sensor' | Fix in code ProcedureDlg, row 1851 |
|
||||
|
||||
@@ -72,6 +72,9 @@ namespace TBF.Rig.Ambient.Greco
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
AmbientCfg()
|
||||
{
|
||||
|
||||
@@ -66,6 +66,9 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
[XmlIgnore]
|
||||
public IList<GEdge> EdgesToSet { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
UniCBCfg()
|
||||
{
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
///
|
||||
using Common;
|
||||
using log4net;
|
||||
using SchematicDrawing;
|
||||
///
|
||||
/// Copyright (c) 2016-2020 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Boxes;
|
||||
using TBF.Rig.Keithley.Multimeter_2010_RS232;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Keithley.Multimeter_2010_RS232;
|
||||
|
||||
namespace TBF.Rig.Keithley.TempMeter
|
||||
{
|
||||
public class TempMeter : ComponentBase, GenericDevices.ITempMeter, GenericDevices.IHasCalendarEvents, SchematicDrawing.IDrawingItCmpnt
|
||||
{
|
||||
public class TempMeter : ComponentBase, GenericDevices.ITempMeter, GenericDevices.IHasCalendarEvents, IDrawingItCmpntWithMeasuredVal
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(TempMeter));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
@@ -36,9 +37,17 @@ namespace TBF.Rig.Keithley.TempMeter
|
||||
/// Dictionaries to maintain separate operations for each FloatBox argument
|
||||
Dictionary<DoubleBox, IOperation> operations;
|
||||
Dictionary<DoubleBox, IOperation> operations2;
|
||||
public bool IsOffline
|
||||
{
|
||||
get { return tempMtrCfg.IsOffline; }
|
||||
set { tempMtrCfg.IsOffline = value; }
|
||||
}
|
||||
|
||||
int invalidStreak = 0;
|
||||
const int OfflineAfterInvalid = 30;
|
||||
|
||||
|
||||
public TempMeter() { }
|
||||
public TempMeter() { }
|
||||
|
||||
public TempMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@@ -93,39 +102,66 @@ namespace TBF.Rig.Keithley.TempMeter
|
||||
|
||||
public double ReadTemperature()
|
||||
{
|
||||
double resistance = Multimeter.ReadResistance(tempMtrCfg.Channel);
|
||||
// In non-Normal modes do not perform offline detection here
|
||||
if (Cfg.DebugLevel != DebugMode.Normal)
|
||||
{
|
||||
if (Cfg.DebugLevel == DebugMode.Simulate)
|
||||
return 20.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double temperature = 0;
|
||||
if (resistance > 0 && resistance < 2000)
|
||||
{
|
||||
if (tempMtrCfg.UseITS90)
|
||||
{
|
||||
temperature = Formulas.PlatinumResistanceTM_ITS90_R2T(resistance,
|
||||
tempMtrCfg.R001C,
|
||||
tempMtrCfg.a7,
|
||||
tempMtrCfg.b7,
|
||||
tempMtrCfg.c7);
|
||||
}
|
||||
else
|
||||
{
|
||||
temperature = Formulas.PlatinumResistanceTM_ITS27_R2T(resistance,
|
||||
tempMtrCfg.R0,
|
||||
tempMtrCfg.A,
|
||||
tempMtrCfg.B);
|
||||
}
|
||||
double resistance;
|
||||
|
||||
log.DebugFormat("Ch = {0}, R = {1} Ohm, T = {2} °C", Channel, resistance.ToString("F3"), temperature.ToString("F3"));
|
||||
}
|
||||
try
|
||||
{
|
||||
resistance = Multimeter.ReadResistance(tempMtrCfg.Channel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
invalidStreak++;
|
||||
|
||||
return temperature;
|
||||
if (invalidStreak >= OfflineAfterInvalid)
|
||||
IsOffline = true;
|
||||
|
||||
log.WarnFormat("Keithley TempMeter {0} ch={1}: ReadResistance failed ({2}/{3}): {4}",
|
||||
Name, Channel, invalidStreak, OfflineAfterInvalid, ex.Message);
|
||||
|
||||
return 0; // or keep last value, or double.NaN
|
||||
}
|
||||
|
||||
// Valid resistance => online
|
||||
invalidStreak = 0;
|
||||
IsOffline = false;
|
||||
|
||||
double temperature;
|
||||
if (tempMtrCfg.UseITS90)
|
||||
{
|
||||
temperature = Formulas.PlatinumResistanceTM_ITS90_R2T(resistance,
|
||||
tempMtrCfg.R001C,
|
||||
tempMtrCfg.a7,
|
||||
tempMtrCfg.b7,
|
||||
tempMtrCfg.c7);
|
||||
}
|
||||
else
|
||||
{
|
||||
temperature = Formulas.PlatinumResistanceTM_ITS27_R2T(resistance,
|
||||
tempMtrCfg.R0,
|
||||
tempMtrCfg.A,
|
||||
tempMtrCfg.B);
|
||||
}
|
||||
|
||||
log.DebugFormat("Ch = {0}, R = {1} Ohm, T = {2} °C",
|
||||
Channel, resistance.ToString("F3"), temperature.ToString("F3"));
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: TempDone, Error
|
||||
/// </summary>
|
||||
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
|
||||
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadTempOp(ref DoubleBox temp)
|
||||
/// <summary>
|
||||
/// Events: TempDone, Error
|
||||
/// </summary>
|
||||
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
|
||||
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadTempOp(ref DoubleBox temp)
|
||||
{
|
||||
IOperation operation;
|
||||
if (operations.TryGetValue(temp, out operation))
|
||||
|
||||
@@ -62,8 +62,11 @@ namespace TBF.Rig.Keithley.TempMeter
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
|
||||
@@ -81,9 +81,12 @@ namespace TBF.Rig.MettlerToledo.Standard
|
||||
[XmlIgnore]
|
||||
public double MsrdValLimHi { get { return Capacity; } set { } }
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
BalanceCfg()
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
BalanceCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
|
||||
@@ -68,8 +68,11 @@ namespace TBF.Rig.Modbus.Ambient.Comet
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
AmbientCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
AmbientCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
Format = string.Empty;
|
||||
|
||||
@@ -61,8 +61,11 @@ namespace TBF.Rig.Modbus.Meret.AdjustableScale
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
AdjustableMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
AdjustableMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
///
|
||||
using AppDiagnostic;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using SchematicDrawing;
|
||||
using SharedComponents;
|
||||
///
|
||||
/// Copyright (c) 2016-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using SchematicDrawing;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
@@ -35,9 +37,17 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
public string AltString { get { return string.Empty; } }
|
||||
|
||||
int ticketNumber; /// 0 .. number of devices registered for regular polling - 1
|
||||
public bool IsOffline
|
||||
{
|
||||
get { return pressureMtrCfg.IsOffline; }
|
||||
set { pressureMtrCfg.IsOffline = value; }
|
||||
}
|
||||
|
||||
int silentCycles = 0;
|
||||
const int OfflineAfterSilentCycles = 30;
|
||||
|
||||
|
||||
public PressureMeter() { }
|
||||
public PressureMeter() { }
|
||||
|
||||
public PressureMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@@ -59,6 +69,9 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
modbus.ComponentNames[pressureMtrCfg.ModbusAddress] = Name;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
|
||||
IsOffline = true;
|
||||
silentCycles = OfflineAfterSilentCycles;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -68,25 +81,85 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal && modbus.ReceivedTelegrams[pressureMtrCfg.ModbusAddress].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[pressureMtrCfg.ModbusAddress].Dequeue();
|
||||
if (telegram.Length == 9 && telegram[1] == 4 && telegram[2] == 4)
|
||||
{
|
||||
/// Swap byte order
|
||||
byte t1 = telegram[3];
|
||||
byte t2 = telegram[4];
|
||||
byte t3 = telegram[5];
|
||||
byte t4 = telegram[6];
|
||||
telegram[3] = t4;
|
||||
telegram[4] = t3;
|
||||
telegram[5] = t2;
|
||||
telegram[6] = t1;
|
||||
if (DebugLevel != DebugMode.Normal)
|
||||
return;
|
||||
|
||||
receivedPressure = Units.ConvertFrom(Unit.kPa, System.BitConverter.ToSingle(telegram, 3));
|
||||
bool gotValidResponse = false;
|
||||
|
||||
if (DebugLevel == DebugMode.Normal && modbus.ReceivedTelegrams[pressureMtrCfg.ModbusAddress].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[pressureMtrCfg.ModbusAddress].Dequeue();
|
||||
if (telegram.Length == 9 && telegram[1] == 4 && telegram[2] == 4)
|
||||
{
|
||||
/// Swap byte order
|
||||
byte t1 = telegram[3];
|
||||
byte t2 = telegram[4];
|
||||
byte t3 = telegram[5];
|
||||
byte t4 = telegram[6];
|
||||
telegram[3] = t4;
|
||||
telegram[4] = t3;
|
||||
telegram[5] = t2;
|
||||
telegram[6] = t1;
|
||||
|
||||
receivedPressure = Units.ConvertFrom(Unit.kPa, System.BitConverter.ToSingle(telegram, 3));
|
||||
log.WarnFormat("Pressure: {0}={1}bar", Name, receivedPressure.ToString("F3"));
|
||||
|
||||
gotValidResponse = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string telHex = telegram == null ? "<null>" : BitConverter.ToString(telegram);
|
||||
|
||||
string reason;
|
||||
if (telegram == null) reason = "null telegram";
|
||||
else if (telegram.Length != 9) reason = $"unexpected length (expected 9, got {telegram.Length})";
|
||||
else if (telegram.Length > 1 && telegram[1] != 4) reason = $"unexpected function (expected 0x04, got 0x{telegram[1]:X2})";
|
||||
else if (telegram.Length > 2 && telegram[2] != 4) reason = $"unexpected bytecount (expected 0x04, got 0x{telegram[2]:X2})";
|
||||
else reason = "unknown mismatch";
|
||||
|
||||
//LiveLogCache.Instance.AddLog(string.Format(
|
||||
// ">> RunDeviceBefore() >> component: {0} bad received telegram: {1} data={2}",
|
||||
// Name,
|
||||
// reason,
|
||||
// telHex));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool debugOk = (DebugLevel == DebugMode.Normal);
|
||||
int addr = pressureMtrCfg.ModbusAddress;
|
||||
|
||||
try
|
||||
{
|
||||
var q = modbus.ReceivedTelegrams[addr];
|
||||
int qCount = (q == null) ? -1 : q.Count;
|
||||
|
||||
//LiveLogCache.Instance.AddLog(string.Format(
|
||||
// ">> RunDeviceBefore() >> component: {0} condition failed | DebugOk={1} | Addr={2} | QueueNull={3} | QueueCount={4} | silentCycles={5}",
|
||||
// Name, debugOk, addr, (q == null), qCount, silentCycles));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//LiveLogCache.Instance.AddLog(string.Format(
|
||||
// ">> RunDeviceBefore() >> component: {0} condition failed | DebugOk={1} | Addr={2} | silentCycles={3} | EXCEPTION={4}",
|
||||
// Name, debugOk, addr, silentCycles, ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
if (gotValidResponse)
|
||||
{
|
||||
silentCycles = 0;
|
||||
IsOffline = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
silentCycles++;
|
||||
if (silentCycles >= OfflineAfterSilentCycles)
|
||||
{
|
||||
IsOffline = true;
|
||||
//LiveLogCache.Instance.AddLog(string.Format(">> RunDeviceBefore() >> component: {0} IsOffline", Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter()
|
||||
|
||||
@@ -57,8 +57,11 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
PressureMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
PressureMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
@@ -93,7 +96,7 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
"Modbus address", /// 0
|
||||
"Default pressure", /// 1
|
||||
"Display format", /// 2
|
||||
"Unit of pressure", /// 3
|
||||
"Units of pressure", /// 3
|
||||
"Pressure limit Lo", /// 4
|
||||
"Pressure limit Hi", /// 5
|
||||
};
|
||||
|
||||
@@ -59,8 +59,11 @@ namespace TBF.Rig.Modbus.TempControl.Easytherm
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
public ProcParams ProcParams;
|
||||
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
|
||||
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
|
||||
|
||||
@@ -68,9 +68,12 @@ namespace TBF.Rig.Modbus.TempControl.Novus
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
public ProcParams ProcParams;
|
||||
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
|
||||
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
///
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
{
|
||||
@@ -46,6 +47,24 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
|
||||
int ticketNumber; /// 0 .. number of devices registered for regular polling - 1
|
||||
|
||||
//[XmlIgnore]
|
||||
public bool IsOffline
|
||||
{
|
||||
get { return tempMtrCfg.IsOffline; }
|
||||
set { tempMtrCfg.IsOffline = value; }
|
||||
}
|
||||
|
||||
// Shared device/channel health tracking (updated by Channel 0)
|
||||
static int grochSilentCycles = 0;
|
||||
static bool grochOffline = true;
|
||||
|
||||
// Per-channel consecutive invalid-value counters
|
||||
static int[] invalidStreak = new int[TempMeterCfg.ChannelsCount];
|
||||
|
||||
// Thresholds
|
||||
const int GrochOfflineAfterCycles = 30; // No valid telegram N cycles => Groch offline
|
||||
const int ChannelOfflineAfterInvalid = 30; // Invalid value N times => channel offline
|
||||
|
||||
|
||||
public TempMeter() { }
|
||||
|
||||
@@ -57,9 +76,17 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
// Ensure shared static health tracking is initialized only once
|
||||
EnsureSharedInitialized();
|
||||
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
/// Only TempMeter with Channel == 0 communicates via the parent Modbus component
|
||||
// Each instance starts from shared states (will become online automatically after valid data)
|
||||
bool channelOffline = invalidStreak[Channel] >= ChannelOfflineAfterInvalid;
|
||||
IsOffline = grochOffline || channelOffline;
|
||||
|
||||
// Only TempMeter with Channel == 0 communicates via the parent Modbus component
|
||||
if (Channel == 0)
|
||||
{
|
||||
modbus = TbfComponents.FindComponent(tempMtrCfg.ParentName) as Common.Modbus;
|
||||
@@ -68,10 +95,13 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
modbus.ComponentNames[0] = Name;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
}
|
||||
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// In simulation you can decide whether to keep IsOffline false
|
||||
IsOffline = false;
|
||||
log.FatalFormat("{0} simulated: {1}", Name, this);
|
||||
}
|
||||
}
|
||||
@@ -110,10 +140,11 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal && Channel == 0)
|
||||
/*if (DebugLevel == DebugMode.Normal && Channel == 0)
|
||||
{
|
||||
/// Only TempMeter with Channel == 0 communicates via the parent Modbus component
|
||||
///
|
||||
|
||||
if (modbus.ReceivedTelegrams[0].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[0].Dequeue();
|
||||
@@ -147,7 +178,20 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (DebugLevel != DebugMode.Normal)
|
||||
return;
|
||||
|
||||
if (Channel == 0)
|
||||
{
|
||||
// update shared state first (process telegrams)
|
||||
UpdateSharedStateFromGroch();
|
||||
}
|
||||
|
||||
// now every instance (including ch0) computes its offline state from fresh shared values
|
||||
bool channelOffline = invalidStreak[Channel] >= ChannelOfflineAfterInvalid;
|
||||
IsOffline = grochOffline || channelOffline;
|
||||
}
|
||||
|
||||
public void RunDeviceAfter()
|
||||
@@ -182,12 +226,21 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: TempDone, Error
|
||||
/// </summary>
|
||||
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
|
||||
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadTempOp(ref DoubleBox temp)
|
||||
// Decide whether the raw value looks valid.
|
||||
// Adjust this to match real device behavior.
|
||||
static bool IsValidRaw(int raw)
|
||||
{
|
||||
if (raw == 0) return false;
|
||||
if (raw == 0xFFFF) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: TempDone, Error
|
||||
/// </summary>
|
||||
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
|
||||
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadTempOp(ref DoubleBox temp)
|
||||
{
|
||||
return new ReadTempOp(this, ref temp);
|
||||
}
|
||||
@@ -202,5 +255,137 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
{
|
||||
return new ReadTempOp(this, ref temp, tempDone);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to class TempMeter
|
||||
static readonly object initLock = new object();
|
||||
static bool sharedInitialized = false;
|
||||
|
||||
static void EnsureSharedInitialized()
|
||||
{
|
||||
if (sharedInitialized) return;
|
||||
|
||||
lock (initLock)
|
||||
{
|
||||
if (sharedInitialized) return;
|
||||
|
||||
// Start as offline until we receive the first valid telegram
|
||||
grochSilentCycles = GrochOfflineAfterCycles;
|
||||
grochOffline = true;
|
||||
|
||||
for (int i = 0; i < TempMeterCfg.ChannelsCount; i++)
|
||||
{
|
||||
invalidStreak[i] = ChannelOfflineAfterInvalid; // start channels as offline until first valid value
|
||||
tempRaw[i] = 0; // optional: reset raw buffer
|
||||
}
|
||||
|
||||
sharedInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSharedStateFromGroch()
|
||||
{
|
||||
bool gotValidTelegram = false;
|
||||
|
||||
// Process all queued telegrams to avoid backlog accumulation
|
||||
while (modbus.ReceivedTelegrams[0].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[0].Dequeue();
|
||||
|
||||
if (telegram.Length != 28)
|
||||
continue;
|
||||
|
||||
byte checksum = 0;
|
||||
for (int i = 0; i < 27; i++)
|
||||
checksum += telegram[i];
|
||||
|
||||
bool isValidGroch =
|
||||
telegram[0] == '\r' &&
|
||||
telegram[1] == '\n' &&
|
||||
telegram[2] == GrochAddress &&
|
||||
telegram[3] == 28 &&
|
||||
telegram[5] == 2 &&
|
||||
telegram[26] == 3 &&
|
||||
telegram[27] == checksum;
|
||||
|
||||
if (!isValidGroch)
|
||||
continue;
|
||||
|
||||
// At least one valid telegram received this cycle
|
||||
gotValidTelegram = true;
|
||||
|
||||
// Extract raw channel values
|
||||
if (TempMeterCfg.ChannelsCount > 0)
|
||||
{
|
||||
int raw = telegram[10] + 256 * telegram[11];
|
||||
tempRaw[0] = raw;
|
||||
invalidStreak[0] = IsValidRaw(raw) ? 0 : invalidStreak[0] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 1)
|
||||
{
|
||||
int raw = telegram[12] + 256 * telegram[13];
|
||||
tempRaw[1] = raw;
|
||||
invalidStreak[1] = IsValidRaw(raw) ? 0 : invalidStreak[1] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 2)
|
||||
{
|
||||
int raw = telegram[14] + 256 * telegram[15];
|
||||
tempRaw[2] = raw;
|
||||
invalidStreak[2] = IsValidRaw(raw) ? 0 : invalidStreak[2] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 3)
|
||||
{
|
||||
int raw = telegram[16] + 256 * telegram[17];
|
||||
tempRaw[3] = raw;
|
||||
invalidStreak[3] = IsValidRaw(raw) ? 0 : invalidStreak[3] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 4)
|
||||
{
|
||||
int raw = telegram[18] + 256 * telegram[19];
|
||||
tempRaw[4] = raw;
|
||||
invalidStreak[4] = IsValidRaw(raw) ? 0 : invalidStreak[4] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 5)
|
||||
{
|
||||
int raw = telegram[20] + 256 * telegram[21];
|
||||
tempRaw[5] = raw;
|
||||
invalidStreak[5] = IsValidRaw(raw) ? 0 : invalidStreak[5] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 6)
|
||||
{
|
||||
int raw = telegram[22] + 256 * telegram[23];
|
||||
tempRaw[6] = raw;
|
||||
invalidStreak[6] = IsValidRaw(raw) ? 0 : invalidStreak[6] + 1;
|
||||
}
|
||||
|
||||
if (TempMeterCfg.ChannelsCount > 7)
|
||||
{
|
||||
int raw = telegram[24] + 256 * telegram[25];
|
||||
tempRaw[7] = raw;
|
||||
invalidStreak[7] = IsValidRaw(raw) ? 0 : invalidStreak[7] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Device-level offline detection
|
||||
if (gotValidTelegram)
|
||||
{
|
||||
grochSilentCycles = 0;
|
||||
grochOffline = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
grochSilentCycles++;
|
||||
|
||||
if (grochSilentCycles >= GrochOfflineAfterCycles)
|
||||
{
|
||||
grochOffline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
{
|
||||
public class TempMeterCfg : ComponentCfgBase, IChildComponentCfg, GenericDevices.ICalibInfoCfg, IParamsProvider,
|
||||
IDrawingItemWithMeasuredVal
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TempMeterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TempMeterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
|
||||
{
|
||||
@@ -26,9 +26,9 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
|
||||
public const int ChannelsCount = 8;
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public int Address; /// 0 0 .. 255
|
||||
public int Channel; /// 1 0 .. 7 (7 = TempMeterCfg.ChannelsCount-1)
|
||||
public double A1; /// 2
|
||||
@@ -65,8 +65,11 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
@@ -113,7 +116,7 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
"A5", /// 6
|
||||
"Default temperature", /// 7
|
||||
"Display format", /// 8
|
||||
"Unit of temperature", /// 9
|
||||
"Units of temperature", /// 9
|
||||
"Temperature limit Lo", /// 10
|
||||
"Temperature limit Hi", /// 11
|
||||
};
|
||||
|
||||
@@ -33,9 +33,17 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
public string AltString { get { return string.Empty; } }
|
||||
|
||||
int ticketNumber; /// 0 .. number of devices registered for regular polling - 1
|
||||
public bool IsOffline
|
||||
{
|
||||
get { return tempMtrCfg.IsOffline; }
|
||||
set { tempMtrCfg.IsOffline = value; }
|
||||
}
|
||||
|
||||
int silentCycles = 0;
|
||||
const int OfflineAfterSilentCycles = 30; // e.g. 5 cycles without valid response
|
||||
|
||||
|
||||
public TempMeter() { }
|
||||
public TempMeter() { }
|
||||
|
||||
public TempMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@@ -50,6 +58,11 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
|
||||
modbus.ComponentNames[tempMtrCfg.ModbusAddress] = Name;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
|
||||
// Start offline until first valid response arrives (optional but consistent)
|
||||
IsOffline = true;
|
||||
silentCycles = OfflineAfterSilentCycles;
|
||||
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
|
||||
@@ -59,25 +72,45 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
/// <summary>Run this device</summary>
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if (modbus.ReceivedTelegrams[tempMtrCfg.ModbusAddress].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[tempMtrCfg.ModbusAddress].Dequeue();
|
||||
if (telegram.Length == 9 && telegram[1] == 4 && telegram[2] == 4)
|
||||
{
|
||||
/// Swap byte order
|
||||
byte t1 = telegram[3];
|
||||
byte t2 = telegram[4];
|
||||
byte t3 = telegram[5];
|
||||
byte t4 = telegram[6];
|
||||
telegram[3] = t4;
|
||||
telegram[4] = t3;
|
||||
telegram[5] = t2;
|
||||
telegram[6] = t1;
|
||||
if (Cfg.DebugLevel != DebugMode.Normal)
|
||||
return;
|
||||
|
||||
receivedTemp = System.BitConverter.ToSingle(telegram, 3);
|
||||
log.WarnFormat("Temperature: {0}={1}°C", Name, receivedTemp.ToString("F1"));
|
||||
}
|
||||
}
|
||||
bool gotValidResponse = false;
|
||||
|
||||
while (modbus.ReceivedTelegrams[tempMtrCfg.ModbusAddress].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[tempMtrCfg.ModbusAddress].Dequeue();
|
||||
|
||||
// Presence = valid response frame
|
||||
if (telegram.Length == 9 && telegram[1] == 4 && telegram[2] == 4)
|
||||
{
|
||||
gotValidResponse = true;
|
||||
|
||||
// Optional: still parse temperature for display/use (does not affect presence)
|
||||
byte t1 = telegram[3];
|
||||
byte t2 = telegram[4];
|
||||
byte t3 = telegram[5];
|
||||
byte t4 = telegram[6];
|
||||
telegram[3] = t4;
|
||||
telegram[4] = t3;
|
||||
telegram[5] = t2;
|
||||
telegram[6] = t1;
|
||||
|
||||
receivedTemp = BitConverter.ToSingle(telegram, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (gotValidResponse)
|
||||
{
|
||||
silentCycles = 0;
|
||||
IsOffline = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
silentCycles++;
|
||||
if (silentCycles >= OfflineAfterSilentCycles)
|
||||
IsOffline = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter()
|
||||
@@ -116,6 +149,17 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsValidTemperature(float t)
|
||||
{
|
||||
// Reject NaN/Infinity
|
||||
if (float.IsNaN(t) || float.IsInfinity(t)) return false;
|
||||
|
||||
// Put a reasonable physical range here (adjust to your real use case)
|
||||
if (t < -50.0f || t > 200.0f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: PressureDone, Error
|
||||
/// </summary>
|
||||
|
||||
@@ -58,8 +58,11 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TempMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
@@ -94,7 +97,7 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
"Modbus address", /// 0
|
||||
"Default temperature", /// 1
|
||||
"Display format", /// 2
|
||||
"Unit of temperature", /// 3
|
||||
"Units of temperature", /// 3
|
||||
"Temperature limit Lo", /// 4
|
||||
"Temperature limit Hi", /// 5
|
||||
};
|
||||
|
||||
@@ -49,8 +49,11 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
[XmlIgnore]
|
||||
public IList<GNode> GNodes { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
LevelMeterCfg()
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
LevelMeterCfg()
|
||||
{
|
||||
GNodes = new List<GNode>();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory component 'DatabaseWriter' implements more storing modules
|
||||
/// Mosules:
|
||||
/// * store whole results in database
|
||||
/// * store to specific mexico database structure - not implemented yet
|
||||
/// * store configurable data SQL template to a specific database - not implemented yet
|
||||
/// </summary>
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } } /// For backward compatibility
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new WritingToDb(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new WritingToDb(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new WriterCfg("DatabaseWriter", this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(WriterCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2019 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
public partial class WriteDbCfgCtrl : Configs.ConfigCtrlUtils, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
WriterCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as WriterCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public WriteDbCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void WriterCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (config == null) return;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
connStrTextBox.Text = config.ConnStr;
|
||||
connStr2TextBox.Text = config.ConnStr2;
|
||||
checkPreviousRecordsCheckBox.Checked = config.CheckPreviousRecords;
|
||||
saveTracingRecordsCheckBox.Checked = config.SaveTracingRecords;
|
||||
|
||||
Network.AdapterInfo.RefreshNetAdaptersInfo();
|
||||
IList<Network.AdapterInfo> adapters = Network.AdapterInfo.NetAdapters;
|
||||
|
||||
string cfgAdapter = string.Empty;
|
||||
foreach (Network.AdapterInfo ai in adapters)
|
||||
{
|
||||
string record;
|
||||
|
||||
if (ai.IPAddress == null)
|
||||
{
|
||||
/// This happens with network adapters that currently have no IP address,
|
||||
/// for instance not connected wireless or dial-up adapters
|
||||
record = "???.???.???.???";
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Do not consider IPv6 adapters as well as "Any", "Broadcast", "Loopback" or "None" addresses
|
||||
if ((ai.IPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) ||
|
||||
ai.IPAddress.Equals(IPAddress.Any) ||
|
||||
ai.IPAddress.Equals(IPAddress.Broadcast) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6Any) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6Loopback) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6None) ||
|
||||
ai.IPAddress.Equals(IPAddress.Loopback) ||
|
||||
ai.IPAddress.Equals(IPAddress.None))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
record = ai.IPAddress.ToString();
|
||||
}
|
||||
|
||||
record += " - " + ai.Description;
|
||||
int i = netAdapterComboBox.Items.Add(record);
|
||||
if (ai.Description == config.NetAdapter)
|
||||
{
|
||||
/// Select the adapter currently in the configuration
|
||||
netAdapterComboBox.SelectedIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
/// Select the first one if the adapter from the configuration does not exist on the system
|
||||
if (netAdapterComboBox.SelectedIndex < 0 && netAdapterComboBox.Items.Count > 0)
|
||||
{
|
||||
netAdapterComboBox.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
connStrTextBox.Enabled = true;
|
||||
connStr2TextBox.Enabled = true;
|
||||
netAdapterComboBox.Enabled = true;
|
||||
checkPreviousRecordsCheckBox.Enabled = true;
|
||||
saveTracingRecordsCheckBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
if (config.Name != nameTextBox.Text)
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
}
|
||||
|
||||
flags |= UpdateDifferent(ref config.ConnStr, connStrTextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.ConnStr2, connStr2TextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.CheckPreviousRecords, checkPreviousRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.SaveTracingRecords, saveTracingRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
|
||||
/// Network adapter
|
||||
string strAdapter = netAdapterComboBox.Text;
|
||||
int iDash = strAdapter.IndexOf(" - ");
|
||||
string netAdapter = (iDash < 0) ? "" : strAdapter.Substring(iDash + 3);
|
||||
if (config.NetAdapter != netAdapter)
|
||||
{
|
||||
config.NetAdapter = netAdapter;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
partial class WriteDbCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.connStrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.connStrLabel = new System.Windows.Forms.Label();
|
||||
this.saveTracingRecordsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.checkPreviousRecordsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.netAdapterLabel = new System.Windows.Forms.Label();
|
||||
this.netAdapterComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.connStr2TextBox = new System.Windows.Forms.TextBox();
|
||||
this.connStr2Label = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(117, 32);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(326, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(5, 35);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(38, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name:";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(114, 10);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// connStrTextBox
|
||||
//
|
||||
this.connStrTextBox.Enabled = false;
|
||||
this.connStrTextBox.Location = new System.Drawing.Point(8, 74);
|
||||
this.connStrTextBox.Name = "connStrTextBox";
|
||||
this.connStrTextBox.Size = new System.Drawing.Size(435, 20);
|
||||
this.connStrTextBox.TabIndex = 4;
|
||||
//
|
||||
// connStrLabel
|
||||
//
|
||||
this.connStrLabel.AutoSize = true;
|
||||
this.connStrLabel.Location = new System.Drawing.Point(5, 58);
|
||||
this.connStrLabel.Name = "connStrLabel";
|
||||
this.connStrLabel.Size = new System.Drawing.Size(92, 13);
|
||||
this.connStrLabel.TabIndex = 3;
|
||||
this.connStrLabel.Text = "Connection string:";
|
||||
//
|
||||
// saveTracingRecordsCheckBox
|
||||
//
|
||||
this.saveTracingRecordsCheckBox.AutoSize = true;
|
||||
this.saveTracingRecordsCheckBox.Enabled = false;
|
||||
this.saveTracingRecordsCheckBox.Location = new System.Drawing.Point(117, 221);
|
||||
this.saveTracingRecordsCheckBox.Name = "saveTracingRecordsCheckBox";
|
||||
this.saveTracingRecordsCheckBox.Size = new System.Drawing.Size(177, 17);
|
||||
this.saveTracingRecordsCheckBox.TabIndex = 10;
|
||||
this.saveTracingRecordsCheckBox.Text = "Save production tracing records";
|
||||
this.saveTracingRecordsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkPreviousRecordsCheckBox
|
||||
//
|
||||
this.checkPreviousRecordsCheckBox.AutoSize = true;
|
||||
this.checkPreviousRecordsCheckBox.Enabled = false;
|
||||
this.checkPreviousRecordsCheckBox.Location = new System.Drawing.Point(117, 199);
|
||||
this.checkPreviousRecordsCheckBox.Name = "checkPreviousRecordsCheckBox";
|
||||
this.checkPreviousRecordsCheckBox.Size = new System.Drawing.Size(138, 17);
|
||||
this.checkPreviousRecordsCheckBox.TabIndex = 9;
|
||||
this.checkPreviousRecordsCheckBox.Text = "Check previous records";
|
||||
this.checkPreviousRecordsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// netAdapterLabel
|
||||
//
|
||||
this.netAdapterLabel.AutoSize = true;
|
||||
this.netAdapterLabel.Location = new System.Drawing.Point(5, 147);
|
||||
this.netAdapterLabel.Name = "netAdapterLabel";
|
||||
this.netAdapterLabel.Size = new System.Drawing.Size(89, 13);
|
||||
this.netAdapterLabel.TabIndex = 7;
|
||||
this.netAdapterLabel.Text = "Network adapter:";
|
||||
//
|
||||
// netAdapterComboBox
|
||||
//
|
||||
this.netAdapterComboBox.Enabled = false;
|
||||
this.netAdapterComboBox.FormattingEnabled = true;
|
||||
this.netAdapterComboBox.Location = new System.Drawing.Point(8, 163);
|
||||
this.netAdapterComboBox.Name = "netAdapterComboBox";
|
||||
this.netAdapterComboBox.Size = new System.Drawing.Size(435, 21);
|
||||
this.netAdapterComboBox.TabIndex = 8;
|
||||
//
|
||||
// connStr2TextBox
|
||||
//
|
||||
this.connStr2TextBox.Enabled = false;
|
||||
this.connStr2TextBox.Location = new System.Drawing.Point(8, 118);
|
||||
this.connStr2TextBox.Name = "connStr2TextBox";
|
||||
this.connStr2TextBox.Size = new System.Drawing.Size(434, 20);
|
||||
this.connStr2TextBox.TabIndex = 6;
|
||||
//
|
||||
// connStr2Label
|
||||
//
|
||||
this.connStr2Label.AutoSize = true;
|
||||
this.connStr2Label.Location = new System.Drawing.Point(5, 102);
|
||||
this.connStr2Label.Name = "connStr2Label";
|
||||
this.connStr2Label.Size = new System.Drawing.Size(101, 13);
|
||||
this.connStr2Label.TabIndex = 5;
|
||||
this.connStr2Label.Text = "Connection string 2:";
|
||||
//
|
||||
// TracingCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.connStr2TextBox);
|
||||
this.Controls.Add(this.connStr2Label);
|
||||
this.Controls.Add(this.netAdapterComboBox);
|
||||
this.Controls.Add(this.netAdapterLabel);
|
||||
this.Controls.Add(this.saveTracingRecordsCheckBox);
|
||||
this.Controls.Add(this.checkPreviousRecordsCheckBox);
|
||||
this.Controls.Add(this.connStrTextBox);
|
||||
this.Controls.Add(this.connStrLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "WriteDbCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(450, 250);
|
||||
this.Load += new System.EventHandler(this.WriterCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.TextBox connStrTextBox;
|
||||
private System.Windows.Forms.Label connStrLabel;
|
||||
private System.Windows.Forms.CheckBox saveTracingRecordsCheckBox;
|
||||
private System.Windows.Forms.CheckBox checkPreviousRecordsCheckBox;
|
||||
private System.Windows.Forms.Label netAdapterLabel;
|
||||
private System.Windows.Forms.ComboBox netAdapterComboBox;
|
||||
private System.Windows.Forms.TextBox connStr2TextBox;
|
||||
private System.Windows.Forms.Label connStr2Label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,57 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
///
|
||||
/// Class and file name is preserved for backward compatibility
|
||||
///
|
||||
public class WriterCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(WriterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new WriteDbCfgCtrl(); }
|
||||
|
||||
|
||||
public string ConnStr;
|
||||
public string ConnStr2;
|
||||
public string NetAdapter;
|
||||
public bool CheckPreviousRecords;
|
||||
public bool SaveTracingRecords;
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
WriterCfg()
|
||||
{
|
||||
ParentName = string.Empty;
|
||||
NetAdapter = string.Empty;
|
||||
ConnStr = "server=10.42.128.24; database=sledovanie2020; uid=vyroba2020; pwd=qwerty; charset=utf8;";
|
||||
ConnStr2 = "server=10.42.128.24; database=sledovanie2019; uid=vyroba2019; pwd=qwerty; charset=utf8;";
|
||||
CheckPreviousRecords = true;
|
||||
SaveTracingRecords = true;
|
||||
}
|
||||
|
||||
public WriterCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Name = name;
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, CheckPrev.={1}, SaveRecords={2}, ConnStr={3}, , ConnStr2={4}",
|
||||
Name,
|
||||
CheckPreviousRecords,
|
||||
SaveTracingRecords,
|
||||
ConnStr,
|
||||
ConnStr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Common;
|
||||
using log4net;
|
||||
using NHibernate;
|
||||
using SharedDatabase;
|
||||
using SharedDatabase.Entities;
|
||||
using TBF.Rig.Sequences;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
public enum Retv
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
}
|
||||
|
||||
class DateTimeComparer : IComparer<DateTime>
|
||||
{
|
||||
public int Compare(DateTime x, DateTime y)
|
||||
{
|
||||
return DateTime.Compare(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public class WritingToDb : ComponentBase, IOperation, GenericDevices.IResultsWriter, GenericDevices.IStartInfoReader, Generic.IDevice
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(WritingToDb));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public const string WorkstepName = "Test_bench";
|
||||
|
||||
public OrderInfo DefaultOrder;
|
||||
|
||||
WriterCfg tracingCfg;
|
||||
string workplace
|
||||
{
|
||||
get
|
||||
{
|
||||
TBF.Rig.GenericDevices.IBenchInfo benchInfo = TBF.Rig.Sequences.ProcessData.BenchInfo;
|
||||
return (benchInfo != null) ? benchInfo.TestBenchName : "TestBench";
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress ipAddress;
|
||||
IPAddress netMask;
|
||||
public IPAddress IPAddress { get { return ipAddress; } }
|
||||
public IPAddress NetMask { get { return netMask; } }
|
||||
|
||||
enum OpState
|
||||
{
|
||||
None,
|
||||
CheckPreviousRecordsScheduled,
|
||||
CheckPreviousRecordsRunning,
|
||||
SaveTracingRecordsScheduled,
|
||||
SaveTracingRecordsRunning,
|
||||
}
|
||||
///
|
||||
OpState currentOpState;
|
||||
bool opCompleted;
|
||||
bool anyError;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Watermeters to check at the beginning of the cycle
|
||||
/// </summary>
|
||||
IList<Results.Entities.WaterMeter> waterMeters;
|
||||
|
||||
/// <summary>
|
||||
/// Data (tracing records) to write at the end of cycle
|
||||
/// </summary>
|
||||
Results.Entities.Batch batch;
|
||||
|
||||
public ISessionFactory SessionFactory; /// Factory to create database sessions that is initialized in the constructor
|
||||
|
||||
|
||||
public WritingToDb() {}
|
||||
|
||||
public WritingToDb(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
tracingCfg = cfg as WriterCfg;
|
||||
if (tracingCfg == null) throw new ArgumentException("tracingCfg");
|
||||
|
||||
Network.AdapterInfo.RefreshNetAdaptersInfo();
|
||||
Network.AdapterInfo netadapter = Network.AdapterInfo.GetNetAdapter(tracingCfg.NetAdapter);
|
||||
ipAddress = netadapter.IPAddress;
|
||||
|
||||
netMask = netadapter.NetMask;
|
||||
currentOpState = OpState.None;
|
||||
log.Warn(this.ToString());
|
||||
|
||||
DefaultOrder = null;
|
||||
}
|
||||
|
||||
///
|
||||
/// IDevice interface implementation
|
||||
///
|
||||
public override void Initialize()
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate) return;
|
||||
|
||||
string ipAddress = GetIPAddress();
|
||||
|
||||
///
|
||||
/// Session factory is used to create database sessions
|
||||
///
|
||||
SharedDatabase.TracingDB.SessionFactory = this.SessionFactory =
|
||||
FluentNHibernate.Cfg.Fluently.Configure()
|
||||
.Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard.ConnectionString(tracingCfg.ConnStr))
|
||||
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Process>())
|
||||
.ExposeConfiguration(SharedDatabase.TracingDB.BuildSchema)
|
||||
.BuildSessionFactory();
|
||||
|
||||
try
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
///
|
||||
/// Initialize DefaultOrder
|
||||
///
|
||||
var dfltOrders = session.QueryOver<OrderInfo>()
|
||||
.Where(x => x.POName == "0000001")
|
||||
.And(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
|
||||
.List();
|
||||
if (dfltOrders.Count > 0) DefaultOrder = dfltOrders[0];
|
||||
|
||||
#if !DEBUG
|
||||
///
|
||||
/// Register this test bench in the tracing DB for approx. 2 weeks (RELEASE version only)
|
||||
///
|
||||
SharedDatabase.TracingDB.RegisterWorkplaceObsolete(session,
|
||||
workplace,
|
||||
CurrentUser.UserName(),
|
||||
GetIPAddress(),
|
||||
"<multiple>",
|
||||
WorkstepName,
|
||||
DateTime.Now + new TimeSpan(15, 0, 0, 0));
|
||||
session.Flush();
|
||||
#endif
|
||||
session.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.ErrorFormat("Cannot load a default order from a database or regster this workplace: {0}", ex);
|
||||
DefaultOrder = null;
|
||||
}
|
||||
}
|
||||
///
|
||||
string GetIPAddress()
|
||||
{
|
||||
return (ipAddress != null) ? ipAddress.ToString() : "1.2.3.4";
|
||||
}
|
||||
///
|
||||
public void RunDeviceBefore() { }
|
||||
public void RunDeviceAfter() { }
|
||||
///
|
||||
public void StopDevice()
|
||||
{
|
||||
if (tracingCfg.DebugLevel != DebugMode.Normal) return;
|
||||
|
||||
using (ISession session = SessionFactory.OpenSession())
|
||||
{
|
||||
SharedDatabase.TracingDB.UnregisterWorkplaceObsolete(session, workplace);
|
||||
session.Flush();
|
||||
}
|
||||
}
|
||||
public void StopDevice2() {}
|
||||
|
||||
public IList<OrderInfo> ReadOrders()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
var result = session.QueryOver<OrderInfo>()
|
||||
.Where(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
|
||||
.List();
|
||||
session.Close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.ErrorFormat("ReadOrders() failed: {0}", ex.Message);
|
||||
return new List<OrderInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read reference records belonging to a specified order.
|
||||
/// Used when retrieving housing S/N-s belonging to obtained eRegister numbers.
|
||||
/// </summary>
|
||||
/// <param name="session">DB sesson</param>
|
||||
/// <param name="order">Order</param>
|
||||
/// <returns>List of reference records-s</returns>
|
||||
public IList<ReferenceRecord> ReadRefRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var refRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.POName == order.POName))
|
||||
.List();
|
||||
refRecords.Reverse();
|
||||
|
||||
if (dfltOrder != null && dfltWFlow != null)
|
||||
{
|
||||
var moreRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.POName == dfltOrder.POName))
|
||||
.And(x => (x.Workflow == dfltWFlow.Name))
|
||||
.List();
|
||||
for (int i = moreRecords.Count - 1; i >= 0; i--) refRecords.Add(moreRecords[i]);
|
||||
}
|
||||
|
||||
return refRecords;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Cannot read ref.records from the tracing DB: {0}", exc.Message);
|
||||
return new List<ReferenceRecord>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Read records belonging to a specified order
|
||||
/// </summary>
|
||||
/// <param name="session">DB sesson</param>
|
||||
/// <param name="order">Order</param>
|
||||
/// <returns>List of records</returns>
|
||||
public IList<Record> ReadRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = session.QueryOver<Record>()
|
||||
.JoinQueryOver<ReferenceRecord>(rec => rec.ReferenceRecord)
|
||||
.Where(rr => rr.POName == order.POName)
|
||||
.List();
|
||||
records.Reverse();
|
||||
|
||||
if (dfltOrder != null && dfltWFlow != null)
|
||||
{
|
||||
var moreRecords = session.QueryOver<Record>()
|
||||
.JoinQueryOver<ReferenceRecord>(rec => rec.ReferenceRecord)
|
||||
.Where(rr => (rr.POName == dfltOrder.POName))
|
||||
.And(rr => (rr.Workflow == dfltWFlow.Name))
|
||||
.List();
|
||||
for (int i = moreRecords.Count - 1; i >= 0; i--) records.Add(moreRecords[i]);
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Cannot read records from the tracing DB: {0}", exc.Message);
|
||||
return new List<Record>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads information on start of a cycle, Events: Event.InfoRead
|
||||
/// </summary>
|
||||
/// <param name="waterMeters">Results of water meters</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ReadStartInfoOp(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
if (!tracingCfg.CheckPreviousRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.waterMeters = waterMeters;
|
||||
currentOpState = OpState.CheckPreviousRecordsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file, Events: Event.ResultsWritten
|
||||
/// </summary>
|
||||
/// <param name="procedure">Procedure to print the results of</param>
|
||||
/// <param name="unsortedResults">Results to write into the file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessResultsOp(Results.Entities.Batch batch)
|
||||
{
|
||||
if (!tracingCfg.SaveTracingRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.batch = batch;
|
||||
currentOpState = OpState.SaveTracingRecordsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (currentOpState == OpState.CheckPreviousRecordsScheduled)
|
||||
{
|
||||
currentOpState = OpState.CheckPreviousRecordsRunning;
|
||||
}
|
||||
else if (currentOpState == OpState.SaveTracingRecordsScheduled)
|
||||
{
|
||||
currentOpState = OpState.SaveTracingRecordsRunning;
|
||||
}
|
||||
|
||||
opCompleted = false;
|
||||
anyError = false;
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsWritten or Event.Error</returns>
|
||||
public Event Run()
|
||||
{
|
||||
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
|
||||
|
||||
if (currentOpState == OpState.CheckPreviousRecordsRunning)
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate) return Event.InfoRead;
|
||||
if (opCompleted) return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
|
||||
/// Run once
|
||||
opCompleted = true;
|
||||
if (CheckPreviousRecords(waterMeters) != Retv.OK) anyError = true;
|
||||
return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
}
|
||||
|
||||
if (currentOpState == OpState.SaveTracingRecordsRunning)
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate || batch.WaterMeters.Count == 0) return Event.ResultsWritten;
|
||||
if (opCompleted) return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
|
||||
/// Run once
|
||||
opCompleted = true;
|
||||
if (SaveTracingRecords(batch) != Retv.OK) anyError = true;
|
||||
|
||||
if (anyError && !string.IsNullOrEmpty(SharedDatabase.EventsDB.ConnectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
NHibernate.ISession session = SharedDatabase.EventsDB.CreateSession();
|
||||
SharedDatabase.EventsDB.LoadSubscribers(session);
|
||||
|
||||
TBF.UiBridge.Bridge.TriggerEvent(session, Name, EventClass.ComputerResources, Severity.Error,
|
||||
string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB: Číslo dávky={0}", batch.BatchNr),
|
||||
string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB\r\nČíslo dávky = {0}", batch.BatchNr),
|
||||
SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Triggering event(s) failed: {0}", exc.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
currentOpState = OpState.None;
|
||||
}
|
||||
|
||||
|
||||
Retv CheckPreviousRecords(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
Retv retVal = Retv.Error;
|
||||
|
||||
var sampleWM = waterMeters.FirstOrDefault<Results.Entities.WaterMeter>(x => x != null && x.Disabled == false);
|
||||
if (sampleWM != null)
|
||||
{
|
||||
using (ISession session = SessionFactory.OpenSession())
|
||||
{
|
||||
for (int i = 0; i < waterMeters.Count; i++)
|
||||
{
|
||||
Results.Entities.WaterMeter wm = waterMeters[i];
|
||||
|
||||
if ((wm != null) && !wm.Disabled)
|
||||
{
|
||||
CheckPreviousRecordOfSingleWM(session, wm);
|
||||
}
|
||||
}
|
||||
|
||||
retVal = Retv.OK; /// Successfully completed (regardless of wm.LastRecordIsNok)
|
||||
}
|
||||
}
|
||||
|
||||
return retVal; /// Returns Retv.Error if checking not completed successfully
|
||||
}
|
||||
|
||||
|
||||
Retv CheckPreviousRecordOfSingleWM(ISession session, Results.Entities.WaterMeter wm)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(wm.SerialNr) && ProcessData.WorkflowSummary != null)
|
||||
{
|
||||
/// Get all reference records with Code == SerialNr from all worksteps different from 'Test_bench'
|
||||
var refRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(rr => (rr.Code1 == wm.SerialNr))
|
||||
.List();
|
||||
|
||||
if (refRecords.Count == 1)
|
||||
{
|
||||
ReferenceRecord refRecord = refRecords[0];
|
||||
StepRecord previousStep = string.IsNullOrEmpty(ProcessData.WorkflowSummary.PreviousWorkstepName) ? null
|
||||
: refRecord.StepRecords.FirstOrDefault(x => x.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName);
|
||||
|
||||
if (refRecord.Name1 == ProcessData.WorkflowSummary.Part1Name &&
|
||||
refRecord.Name2 == ProcessData.WorkflowSummary.Part2Name &&
|
||||
(ProcessData.WorkflowSummary.PreviousWorkstepName == null ||
|
||||
(previousStep != null && previousStep.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName)))
|
||||
{
|
||||
wm.Workflow = ProcessData.WorkflowSummary.Workflow.Name;
|
||||
wm.LastRecordIsNok = false; /// OK
|
||||
return Retv.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// S/N is missing OR no records found OR workflows do not match OR previous StepRecord is missing
|
||||
wm.Workflow = string.Empty;
|
||||
wm.LastRecordIsNok = true; /// NOK
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write results of a batch of water meters to the DB
|
||||
/// </summary>
|
||||
/// <param name="session">DB session</param>
|
||||
/// <param name="batch">Batch entity</param>
|
||||
Retv SaveTracingRecords(Results.Entities.Batch batch)
|
||||
{
|
||||
ITransaction transaction = null;
|
||||
ISession session = null;
|
||||
|
||||
var order = ProcessData.OrderInfo as SharedDatabase.Entities.OrderInfo;
|
||||
if (order != null && ProcessData.WorkflowSummary != null && !string.IsNullOrEmpty(ProcessData.WorkflowSummary.WorkstepName))
|
||||
{
|
||||
///
|
||||
/// Save to regular tracing DB
|
||||
///
|
||||
try
|
||||
{
|
||||
session = SessionFactory.OpenSession();
|
||||
transaction = session.BeginTransaction();
|
||||
|
||||
string workplace = (ProcessData.BenchInfo != null) ? ProcessData.BenchInfo.TestBenchName : "TestBench";
|
||||
int writtenRecordsCount = 0;
|
||||
foreach (var wm in batch.WaterMeters)
|
||||
{
|
||||
if (!wm.Disabled && !string.IsNullOrEmpty(wm.SerialNr))
|
||||
{
|
||||
writtenRecordsCount += SaveSingleWM2DB(session, wm, order.POName, ProcessData.WorkflowSummary, workplace);
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
session.Flush();
|
||||
|
||||
log.WarnFormat("Batch {0}: {1} of {2} watermeters written to the regular production tracing DB",
|
||||
batch.BatchNr, writtenRecordsCount, batch.WaterMeters.Count);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
if (transaction != null && !transaction.WasCommitted) transaction.Rollback();
|
||||
|
||||
log.ErrorFormat("Failed to write results of batch {0} to production tracing DB: {1}",
|
||||
batch.BatchNr, exc.Message);
|
||||
|
||||
return Retv.Error;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
session.Close();
|
||||
session.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write one meter results to the DB
|
||||
/// </summary>
|
||||
/// <param name="session">DB session</param>
|
||||
/// <param name="wm">Watermeter entity</param>
|
||||
int SaveSingleWM2DB(ISession session, Results.Entities.WaterMeter wm, string poName, WorkflowSummary wflowSummary, string worplace)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wflowSummary.WorkstepName)) return 0;
|
||||
|
||||
IList<ReferenceRecord> existingRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.Code1 == wm.SerialNr))
|
||||
.List();
|
||||
if (existingRecords.Count > 1)
|
||||
{
|
||||
/// Unexpected error
|
||||
log.ErrorFormat("Multiple reference records exist: Code1 = {0}", wm.SerialNr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Reference record
|
||||
///
|
||||
ReferenceRecord refRecord = null;
|
||||
if (existingRecords.Count == 1)
|
||||
{
|
||||
/// TODO: Check if the selected worflow is the same as in the found record
|
||||
refRecord = existingRecords[0];
|
||||
|
||||
refRecord.POName = poName;
|
||||
refRecord.Workflow = wflowSummary.Workflow.Name;
|
||||
refRecord.Code2 = wm.SerialNrAux;
|
||||
refRecord.Code3 = wm.CompleteSerialNr;
|
||||
refRecord.Code4 = wm.RadioAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
refRecord = new ReferenceRecord(poName,
|
||||
wflowSummary.Workflow.Name,
|
||||
wflowSummary.Part1Name, /// PCB (iPERL) or housing (620/640) SAP number
|
||||
wm.SerialNr, /// PcbNumber (iPERL) or housing S/N (620/640)
|
||||
wflowSummary.Part2Name, /// Flowtube SAP nummber (iPERL) or "eRegister#" (640) or empty
|
||||
wm.SerialNrAux, /// Flowtube S/N (iPERL) or eRegister number (640) or empty
|
||||
wm.CompleteSerialNr, /// Complete assigned S/N
|
||||
wm.RadioAddress); /// Radio address (iPERL and 640)
|
||||
}
|
||||
|
||||
///
|
||||
/// Step record
|
||||
///
|
||||
StepRecord stepRecord = new StepRecord(refRecord,
|
||||
wflowSummary.WorkstepName,
|
||||
workplace,
|
||||
Common.CurrentUser.UserName(),
|
||||
wm.PassedFromTests() ? 0 : 1);
|
||||
if (refRecord.StepRecords == null)
|
||||
{
|
||||
refRecord.StepRecords = new List<StepRecord> { stepRecord };
|
||||
}
|
||||
else
|
||||
{
|
||||
refRecord.StepRecords.Add(stepRecord);
|
||||
}
|
||||
|
||||
session.SaveOrUpdate(refRecord);
|
||||
session.SaveOrUpdate(stepRecord);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.implementations;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
public class Factory: IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return this.GetType().Namespace.Substring(8); } }
|
||||
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new GenesisSmartReader(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new GenesisSmartReader(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new GenesisCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(GenesisCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
public class GenesisCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(GenesisCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new GenesisCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public bool UseTcpIP;
|
||||
public string OptoIPAddress;
|
||||
public ushort OptoTcpipPortNr;
|
||||
public int HeadCommunicationComPortNr;
|
||||
public int OptoComPortNr;
|
||||
public int RfidComPortNr; /// 0 = use MuxBoardNr
|
||||
public int MuxBoardNr; /// 0 = use RfidComPort(Nr), otherwise mux. board nr. 1 .. 4
|
||||
public int Group; /// Number written to QuidoRS to connct the watermeter to RfidComPort, 1 .. 10
|
||||
public CommunicationInterface CommunicationInterface; /// Communication Interface: RFID or NFC
|
||||
///
|
||||
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
public ProcParams ProcParams;
|
||||
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
|
||||
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
|
||||
|
||||
[XmlIgnore]
|
||||
public MeterType MeterType { get { return (ProcParams != null) ? ProcParams.MeterType : MeterType.AutoDetect; } }
|
||||
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
GenesisCfg()
|
||||
{
|
||||
Name = "Genesis";
|
||||
ParentName = string.Empty;
|
||||
OptoComPortNr = 10;
|
||||
RfidComPortNr = 0; /// = use mux. board
|
||||
MuxBoardNr = 1;
|
||||
ProcParams = CreateProcParamsProvider() as ProcParams;
|
||||
CommunicationInterface = CommunicationInterface.RFID;
|
||||
HeadCommunicationComPortNr = 0;
|
||||
}
|
||||
|
||||
public GenesisCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return $"{Name} Group1 (mux#)={MuxBoardNr}, Group2={Group}, Opto=Com{OptoComPortNr}, {CommunicationInterface}=Com{RfidComPortNr}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
public partial class GenesisCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
GenesisCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as GenesisCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public GenesisCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void WaterMeterCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
nameLabel.Text = Strings.Name;
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
nameTextBox.Text = config.Name;
|
||||
radioButton1.Checked = config.UseTcpIP;
|
||||
radioButton2.Checked = !config.UseTcpIP;
|
||||
ipAddressTextBox.Text = (config.OptoIPAddress != null) ? config.OptoIPAddress : "0.0.0.0";
|
||||
tcpipPortTextBox.Text = config.OptoTcpipPortNr.ToString();
|
||||
headPortNrTextBox.Text = config.HeadCommunicationComPortNr.ToString();
|
||||
optoSerialPortTextBox.Text = config.OptoComPortNr.ToString();
|
||||
rfidPortNrTextBox.Text = config.RfidComPortNr.ToString();
|
||||
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
groupTextBox.Text = config.Group.ToString();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new GenesisHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
radioButton1.Enabled = true;
|
||||
radioButton2.Enabled = true;
|
||||
ipAddressTextBox.Enabled = true;
|
||||
tcpipPortTextBox.Enabled = true;
|
||||
optoSerialPortTextBox.Enabled = true;
|
||||
rfidPortNrTextBox.Enabled = true;
|
||||
headPortNrTextBox.Enabled = true;
|
||||
muxBoardNrTextBox.Enabled = true;
|
||||
groupTextBox.Enabled = true;
|
||||
comboBoxCommunicationInterface.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
if (radioButton1.Checked)
|
||||
{
|
||||
IPAddress dummyIPAddress;
|
||||
if (!IPAddress.TryParse(ipAddressTextBox.Text, out dummyIPAddress))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'IP address' is not valid";
|
||||
}
|
||||
|
||||
ushort sdummy;
|
||||
if (!ushort.TryParse(tcpipPortTextBox.Text, out sdummy))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'TCP/IP port nr.' is not valid";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!int.TryParse(optoSerialPortTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Opto serial port nr.' is not valid";
|
||||
}
|
||||
}
|
||||
|
||||
if (!int.TryParse(rfidPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'RFID serial port nr.' is not valid";
|
||||
}
|
||||
|
||||
if (!int.TryParse(headPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Head communication serial port nr.' is not valid";
|
||||
}
|
||||
|
||||
if (!int.TryParse(muxBoardNrTextBox.Text, out dummy) || dummy < 1 || dummy > 4)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, muxBoardNrLabel.Text);
|
||||
}
|
||||
|
||||
if (!int.TryParse(groupTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, groupLabel.Text);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
config.Name = nameTextBox.Text;
|
||||
|
||||
if (radioButton1.Checked)
|
||||
{
|
||||
config.UseTcpIP = true;
|
||||
config.OptoIPAddress = ipAddressTextBox.Text;
|
||||
config.OptoTcpipPortNr = ushort.Parse(tcpipPortTextBox.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.UseTcpIP = false;
|
||||
config.OptoComPortNr = int.Parse(optoSerialPortTextBox.Text);
|
||||
}
|
||||
|
||||
config.RfidComPortNr = int.Parse(rfidPortNrTextBox.Text);
|
||||
config.MuxBoardNr = int.Parse(muxBoardNrTextBox.Text);
|
||||
config.Group = int.Parse(groupTextBox.Text);
|
||||
config.CommunicationInterface = (CommunicationInterface)comboBoxCommunicationInterface.SelectedIndex;
|
||||
config.HeadCommunicationComPortNr = int.Parse(headPortNrTextBox.Text);
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
partial class GenesisCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.comboBoxCommunicationInterface = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.rfidPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.rfidSerialPortNrLabel = new System.Windows.Forms.Label();
|
||||
this.optoDataGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.tcpipPortLabel = new System.Windows.Forms.Label();
|
||||
this.tcpipPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.ipAddressLabel = new System.Windows.Forms.Label();
|
||||
this.ipAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.radioButton1 = new System.Windows.Forms.RadioButton();
|
||||
this.radioButton2 = new System.Windows.Forms.RadioButton();
|
||||
this.optoSerialPortLabel = new System.Windows.Forms.Label();
|
||||
this.optoSerialPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.groupTextBox = new System.Windows.Forms.TextBox();
|
||||
this.groupLabel = new System.Windows.Forms.Label();
|
||||
this.muxBoardNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.muxBoardNrLabel = new System.Windows.Forms.Label();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.headPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.optoDataGroupBox.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Controls.Add(this.tabPage1);
|
||||
this.tabControl1.Controls.Add(this.tabPage2);
|
||||
this.tabControl1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tabControl1.Name = "tabControl1";
|
||||
this.tabControl1.SelectedIndex = 0;
|
||||
this.tabControl1.Size = new System.Drawing.Size(611, 432);
|
||||
this.tabControl1.TabIndex = 0;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.groupBox2);
|
||||
this.tabPage1.Controls.Add(this.label4);
|
||||
this.tabPage1.Controls.Add(this.label3);
|
||||
this.tabPage1.Controls.Add(this.groupBox1);
|
||||
this.tabPage1.Controls.Add(this.optoDataGroupBox);
|
||||
this.tabPage1.Controls.Add(this.groupTextBox);
|
||||
this.tabPage1.Controls.Add(this.groupLabel);
|
||||
this.tabPage1.Controls.Add(this.muxBoardNrTextBox);
|
||||
this.tabPage1.Controls.Add(this.muxBoardNrLabel);
|
||||
this.tabPage1.Controls.Add(this.nameTextBox);
|
||||
this.tabPage1.Controls.Add(this.nameLabel);
|
||||
this.tabPage1.Controls.Add(this.classNameLabel);
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 25);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage1.Size = new System.Drawing.Size(603, 403);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "Config";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(208, 101);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(40, 16);
|
||||
this.label4.TabIndex = 25;
|
||||
this.label4.Text = "1 .. 10";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(208, 72);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(33, 16);
|
||||
this.label3.TabIndex = 24;
|
||||
this.label3.Text = "1 .. 4";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.comboBoxCommunicationInterface);
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
this.groupBox1.Controls.Add(this.rfidPortNrTextBox);
|
||||
this.groupBox1.Controls.Add(this.rfidSerialPortNrLabel);
|
||||
this.groupBox1.Location = new System.Drawing.Point(10, 259);
|
||||
this.groupBox1.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Padding = new System.Windows.Forms.Padding(4);
|
||||
this.groupBox1.Size = new System.Drawing.Size(552, 68);
|
||||
this.groupBox1.TabIndex = 23;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "RFID / NFC communication (in case mux. board is not used)";
|
||||
//
|
||||
// comboBoxCommunicationInterface
|
||||
//
|
||||
this.comboBoxCommunicationInterface.Enabled = false;
|
||||
this.comboBoxCommunicationInterface.FormattingEnabled = true;
|
||||
this.comboBoxCommunicationInterface.Items.AddRange(new object[] {
|
||||
"RFID",
|
||||
"NFC"});
|
||||
this.comboBoxCommunicationInterface.Location = new System.Drawing.Point(201, 27);
|
||||
this.comboBoxCommunicationInterface.Name = "comboBoxCommunicationInterface";
|
||||
this.comboBoxCommunicationInterface.Size = new System.Drawing.Size(71, 24);
|
||||
this.comboBoxCommunicationInterface.TabIndex = 9;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(41, 30);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(153, 16);
|
||||
this.label1.TabIndex = 8;
|
||||
this.label1.Text = "Communication Interface";
|
||||
//
|
||||
// rfidPortNrTextBox
|
||||
//
|
||||
this.rfidPortNrTextBox.Enabled = false;
|
||||
this.rfidPortNrTextBox.Location = new System.Drawing.Point(439, 26);
|
||||
this.rfidPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.rfidPortNrTextBox.Name = "rfidPortNrTextBox";
|
||||
this.rfidPortNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.rfidPortNrTextBox.TabIndex = 7;
|
||||
//
|
||||
// rfidSerialPortNrLabel
|
||||
//
|
||||
this.rfidSerialPortNrLabel.AutoSize = true;
|
||||
this.rfidSerialPortNrLabel.Location = new System.Drawing.Point(321, 30);
|
||||
this.rfidSerialPortNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.rfidSerialPortNrLabel.Name = "rfidSerialPortNrLabel";
|
||||
this.rfidSerialPortNrLabel.Size = new System.Drawing.Size(88, 16);
|
||||
this.rfidSerialPortNrLabel.TabIndex = 6;
|
||||
this.rfidSerialPortNrLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoDataGroupBox
|
||||
//
|
||||
this.optoDataGroupBox.Controls.Add(this.tcpipPortLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.tcpipPortTextBox);
|
||||
this.optoDataGroupBox.Controls.Add(this.ipAddressLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.ipAddressTextBox);
|
||||
this.optoDataGroupBox.Controls.Add(this.radioButton1);
|
||||
this.optoDataGroupBox.Controls.Add(this.radioButton2);
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortTextBox);
|
||||
this.optoDataGroupBox.Location = new System.Drawing.Point(10, 131);
|
||||
this.optoDataGroupBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.optoDataGroupBox.Name = "optoDataGroupBox";
|
||||
this.optoDataGroupBox.Padding = new System.Windows.Forms.Padding(4);
|
||||
this.optoDataGroupBox.Size = new System.Drawing.Size(552, 119);
|
||||
this.optoDataGroupBox.TabIndex = 18;
|
||||
this.optoDataGroupBox.TabStop = false;
|
||||
this.optoDataGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// tcpipPortLabel
|
||||
//
|
||||
this.tcpipPortLabel.AutoSize = true;
|
||||
this.tcpipPortLabel.Location = new System.Drawing.Point(41, 87);
|
||||
this.tcpipPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.tcpipPortLabel.Name = "tcpipPortLabel";
|
||||
this.tcpipPortLabel.Size = new System.Drawing.Size(54, 16);
|
||||
this.tcpipPortLabel.TabIndex = 4;
|
||||
this.tcpipPortLabel.Text = "Port nr..:";
|
||||
//
|
||||
// tcpipPortTextBox
|
||||
//
|
||||
this.tcpipPortTextBox.Enabled = false;
|
||||
this.tcpipPortTextBox.Location = new System.Drawing.Point(143, 84);
|
||||
this.tcpipPortTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tcpipPortTextBox.Name = "tcpipPortTextBox";
|
||||
this.tcpipPortTextBox.Size = new System.Drawing.Size(51, 22);
|
||||
this.tcpipPortTextBox.TabIndex = 5;
|
||||
//
|
||||
// ipAddressLabel
|
||||
//
|
||||
this.ipAddressLabel.AutoSize = true;
|
||||
this.ipAddressLabel.Location = new System.Drawing.Point(41, 59);
|
||||
this.ipAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.ipAddressLabel.Name = "ipAddressLabel";
|
||||
this.ipAddressLabel.Size = new System.Drawing.Size(78, 16);
|
||||
this.ipAddressLabel.TabIndex = 2;
|
||||
this.ipAddressLabel.Text = "IP address.:";
|
||||
//
|
||||
// ipAddressTextBox
|
||||
//
|
||||
this.ipAddressTextBox.Enabled = false;
|
||||
this.ipAddressTextBox.Location = new System.Drawing.Point(143, 55);
|
||||
this.ipAddressTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.ipAddressTextBox.Name = "ipAddressTextBox";
|
||||
this.ipAddressTextBox.Size = new System.Drawing.Size(129, 22);
|
||||
this.ipAddressTextBox.TabIndex = 3;
|
||||
//
|
||||
// radioButton1
|
||||
//
|
||||
this.radioButton1.AutoSize = true;
|
||||
this.radioButton1.Checked = true;
|
||||
this.radioButton1.Enabled = false;
|
||||
this.radioButton1.Location = new System.Drawing.Point(29, 23);
|
||||
this.radioButton1.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.radioButton1.Name = "radioButton1";
|
||||
this.radioButton1.Size = new System.Drawing.Size(99, 20);
|
||||
this.radioButton1.TabIndex = 0;
|
||||
this.radioButton1.TabStop = true;
|
||||
this.radioButton1.Text = "Use TCP/IP";
|
||||
this.radioButton1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radioButton2
|
||||
//
|
||||
this.radioButton2.AutoSize = true;
|
||||
this.radioButton2.Enabled = false;
|
||||
this.radioButton2.Location = new System.Drawing.Point(312, 23);
|
||||
this.radioButton2.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.radioButton2.Name = "radioButton2";
|
||||
this.radioButton2.Size = new System.Drawing.Size(115, 20);
|
||||
this.radioButton2.TabIndex = 1;
|
||||
this.radioButton2.Text = "Use serial port";
|
||||
this.radioButton2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// optoSerialPortLabel
|
||||
//
|
||||
this.optoSerialPortLabel.AutoSize = true;
|
||||
this.optoSerialPortLabel.Location = new System.Drawing.Point(321, 55);
|
||||
this.optoSerialPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.optoSerialPortLabel.Name = "optoSerialPortLabel";
|
||||
this.optoSerialPortLabel.Size = new System.Drawing.Size(88, 16);
|
||||
this.optoSerialPortLabel.TabIndex = 6;
|
||||
this.optoSerialPortLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoSerialPortTextBox
|
||||
//
|
||||
this.optoSerialPortTextBox.Enabled = false;
|
||||
this.optoSerialPortTextBox.Location = new System.Drawing.Point(439, 52);
|
||||
this.optoSerialPortTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.optoSerialPortTextBox.Name = "optoSerialPortTextBox";
|
||||
this.optoSerialPortTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.optoSerialPortTextBox.TabIndex = 7;
|
||||
//
|
||||
// groupTextBox
|
||||
//
|
||||
this.groupTextBox.Enabled = false;
|
||||
this.groupTextBox.Location = new System.Drawing.Point(153, 97);
|
||||
this.groupTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.groupTextBox.Name = "groupTextBox";
|
||||
this.groupTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.groupTextBox.TabIndex = 22;
|
||||
//
|
||||
// groupLabel
|
||||
//
|
||||
this.groupLabel.AutoSize = true;
|
||||
this.groupLabel.Location = new System.Drawing.Point(6, 101);
|
||||
this.groupLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.groupLabel.Name = "groupLabel";
|
||||
this.groupLabel.Size = new System.Drawing.Size(54, 16);
|
||||
this.groupLabel.TabIndex = 21;
|
||||
this.groupLabel.Text = "Group 2";
|
||||
//
|
||||
// muxBoardNrTextBox
|
||||
//
|
||||
this.muxBoardNrTextBox.Enabled = false;
|
||||
this.muxBoardNrTextBox.Location = new System.Drawing.Point(153, 69);
|
||||
this.muxBoardNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.muxBoardNrTextBox.Name = "muxBoardNrTextBox";
|
||||
this.muxBoardNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.muxBoardNrTextBox.TabIndex = 20;
|
||||
//
|
||||
// muxBoardNrLabel
|
||||
//
|
||||
this.muxBoardNrLabel.AutoSize = true;
|
||||
this.muxBoardNrLabel.Location = new System.Drawing.Point(6, 72);
|
||||
this.muxBoardNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.muxBoardNrLabel.Name = "muxBoardNrLabel";
|
||||
this.muxBoardNrLabel.Size = new System.Drawing.Size(131, 16);
|
||||
this.muxBoardNrLabel.TabIndex = 19;
|
||||
this.muxBoardNrLabel.Text = "Group 1 (mux. board)";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(153, 40);
|
||||
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(160, 22);
|
||||
this.nameTextBox.TabIndex = 17;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(6, 44);
|
||||
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(44, 16);
|
||||
this.nameLabel.TabIndex = 16;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(149, 11);
|
||||
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(78, 16);
|
||||
this.classNameLabel.TabIndex = 15;
|
||||
this.classNameLabel.Text = "ClassName";
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 25);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(603, 403);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "Test";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.headPortNrTextBox);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Location = new System.Drawing.Point(10, 335);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(552, 50);
|
||||
this.groupBox2.TabIndex = 26;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Head Communication";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(321, 18);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(88, 16);
|
||||
this.label2.TabIndex = 7;
|
||||
this.label2.Text = "Serial port nr.:";
|
||||
//
|
||||
// headPortNrTextBox
|
||||
//
|
||||
this.headPortNrTextBox.Enabled = false;
|
||||
this.headPortNrTextBox.Location = new System.Drawing.Point(439, 15);
|
||||
this.headPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.headPortNrTextBox.Name = "headPortNrTextBox";
|
||||
this.headPortNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.headPortNrTextBox.TabIndex = 8;
|
||||
//
|
||||
// IperlHeadCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.Name = "GenesisCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(617, 438);
|
||||
this.Load += new System.EventHandler(this.WaterMeterCfgCtrl_Load);
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.optoDataGroupBox.ResumeLayout(false);
|
||||
this.optoDataGroupBox.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.ComboBox comboBoxCommunicationInterface;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox rfidPortNrTextBox;
|
||||
private System.Windows.Forms.Label rfidSerialPortNrLabel;
|
||||
private System.Windows.Forms.GroupBox optoDataGroupBox;
|
||||
private System.Windows.Forms.Label tcpipPortLabel;
|
||||
private System.Windows.Forms.TextBox tcpipPortTextBox;
|
||||
private System.Windows.Forms.Label ipAddressLabel;
|
||||
private System.Windows.Forms.TextBox ipAddressTextBox;
|
||||
private System.Windows.Forms.RadioButton radioButton1;
|
||||
private System.Windows.Forms.RadioButton radioButton2;
|
||||
private System.Windows.Forms.Label optoSerialPortLabel;
|
||||
private System.Windows.Forms.TextBox optoSerialPortTextBox;
|
||||
private System.Windows.Forms.TextBox groupTextBox;
|
||||
private System.Windows.Forms.Label groupLabel;
|
||||
private System.Windows.Forms.TextBox muxBoardNrTextBox;
|
||||
private System.Windows.Forms.Label muxBoardNrLabel;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.TextBox headPortNrTextBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,137 @@
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
partial class GenesisHeadTestCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.optoTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.optoListBox = new System.Windows.Forms.ListBox();
|
||||
this.rfidOutputListBox = new System.Windows.Forms.ListBox();
|
||||
this.RfidTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.rfidCommandComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.commandTestButton = new System.Windows.Forms.Button();
|
||||
this.optoTestGroupBox.SuspendLayout();
|
||||
this.RfidTestGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// optoTestGroupBox
|
||||
//
|
||||
this.optoTestGroupBox.Controls.Add(this.optoListBox);
|
||||
this.optoTestGroupBox.Location = new System.Drawing.Point(5, 4);
|
||||
this.optoTestGroupBox.Name = "optoTestGroupBox";
|
||||
this.optoTestGroupBox.Size = new System.Drawing.Size(591, 161);
|
||||
this.optoTestGroupBox.TabIndex = 2;
|
||||
this.optoTestGroupBox.TabStop = false;
|
||||
this.optoTestGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// optoListBox
|
||||
//
|
||||
this.optoListBox.FormattingEnabled = true;
|
||||
this.optoListBox.ItemHeight = 16;
|
||||
this.optoListBox.Location = new System.Drawing.Point(7, 22);
|
||||
this.optoListBox.Name = "optoListBox";
|
||||
this.optoListBox.Size = new System.Drawing.Size(573, 132);
|
||||
this.optoListBox.TabIndex = 0;
|
||||
//
|
||||
// rfidOutputListBox
|
||||
//
|
||||
this.rfidOutputListBox.FormattingEnabled = true;
|
||||
this.rfidOutputListBox.ItemHeight = 16;
|
||||
this.rfidOutputListBox.Location = new System.Drawing.Point(5, 54);
|
||||
this.rfidOutputListBox.Name = "rfidOutputListBox";
|
||||
this.rfidOutputListBox.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||
this.rfidOutputListBox.Size = new System.Drawing.Size(575, 164);
|
||||
this.rfidOutputListBox.TabIndex = 3;
|
||||
//
|
||||
// RfidTestGroupBox
|
||||
//
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidOutputListBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.label2);
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidCommandComboBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.commandTestButton);
|
||||
this.RfidTestGroupBox.Location = new System.Drawing.Point(5, 171);
|
||||
this.RfidTestGroupBox.Name = "RfidTestGroupBox";
|
||||
this.RfidTestGroupBox.Size = new System.Drawing.Size(591, 224);
|
||||
this.RfidTestGroupBox.TabIndex = 3;
|
||||
this.RfidTestGroupBox.TabStop = false;
|
||||
this.RfidTestGroupBox.Text = "RFID / NFC data";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(2, 25);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 16);
|
||||
this.label2.TabIndex = 2;
|
||||
this.label2.Text = "Command";
|
||||
//
|
||||
// rfidCommandComboBox
|
||||
//
|
||||
this.rfidCommandComboBox.FormattingEnabled = true;
|
||||
this.rfidCommandComboBox.Location = new System.Drawing.Point(86, 19);
|
||||
this.rfidCommandComboBox.Name = "rfidCommandComboBox";
|
||||
this.rfidCommandComboBox.Size = new System.Drawing.Size(341, 24);
|
||||
this.rfidCommandComboBox.TabIndex = 1;
|
||||
//
|
||||
// commandTestButton
|
||||
//
|
||||
this.commandTestButton.Location = new System.Drawing.Point(449, 19);
|
||||
this.commandTestButton.Name = "commandTestButton";
|
||||
this.commandTestButton.Size = new System.Drawing.Size(126, 24);
|
||||
this.commandTestButton.TabIndex = 0;
|
||||
this.commandTestButton.Text = "Send command";
|
||||
this.commandTestButton.UseVisualStyleBackColor = true;
|
||||
this.commandTestButton.MouseClick += new System.Windows.Forms.MouseEventHandler(this.CommandTestButtonClick);
|
||||
//
|
||||
// IperlHeadTestCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.optoTestGroupBox);
|
||||
this.Controls.Add(this.RfidTestGroupBox);
|
||||
this.Name = "GenesisHeadTestCtrl";
|
||||
this.Size = new System.Drawing.Size(611, 432);
|
||||
this.Load += new System.EventHandler(this.UserControl_Load);
|
||||
this.optoTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox optoTestGroupBox;
|
||||
private System.Windows.Forms.ListBox rfidOutputListBox;
|
||||
private System.Windows.Forms.GroupBox RfidTestGroupBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ComboBox rfidCommandComboBox;
|
||||
private System.Windows.Forms.Button commandTestButton;
|
||||
private System.Windows.Forms.ListBox optoListBox;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader
|
||||
{
|
||||
public partial class GenesisHeadTestCtrl : UserControl
|
||||
{
|
||||
private IUniHeadTestCtrl<OptoReceivedEventArgs> _ctrl;
|
||||
private IUniHeadTestCtrl<OptoReceivedEventArgs> Ctrl { get => _ctrl; }
|
||||
|
||||
private GenesisCfg _genesisCfg;
|
||||
private GenesisSmartReader _genesisSmartReader;
|
||||
Thread optoThread;
|
||||
private bool stopWorkerThread;
|
||||
|
||||
public GenesisHeadTestCtrl(GenesisCfg config)
|
||||
{
|
||||
this._ctrl = new GenesisImplHeadTestCtrl();
|
||||
_genesisCfg = config;
|
||||
Ctrl.config = config;
|
||||
InitializeComponent();
|
||||
if (config == null) return;
|
||||
|
||||
//SmartCommunicationForm.TestMethodCfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
foreach(var head in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (head != null && head.Name == config.Name) { Ctrl.ISmartReader = head; }
|
||||
}
|
||||
|
||||
rfidCommandComboBox.DisplayMember = "Name";
|
||||
rfidCommandComboBox.ValueMember = "Value";
|
||||
var items = Ctrl.GetComboOperationsPairs();
|
||||
/*
|
||||
// CTRL+ALT+double click - hidden poweruser menu
|
||||
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
|
||||
{
|
||||
Array.Resize(ref items, items.Length + 1);
|
||||
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
|
||||
}
|
||||
*/
|
||||
rfidCommandComboBox.DataSource = items.Select(i => i.Name).ToArray();
|
||||
|
||||
Ctrl.Initialize();
|
||||
|
||||
Ctrl.OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
|
||||
else
|
||||
this.OnOptoReceived2(sndr, args);
|
||||
});
|
||||
}
|
||||
|
||||
public void OnOptoReceived2(object sender, OptoReceivedEventArgs args)
|
||||
{
|
||||
optoListBox.Items.Insert(0,args.Data);
|
||||
}
|
||||
|
||||
private void CommandTestButtonClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
Ctrl.CommandTestButtonClick(sender, e, new Arguments()
|
||||
{
|
||||
ISmartReader = Ctrl.ISmartReader,
|
||||
OptoListBox = optoListBox,
|
||||
RfidCommandComboBox = rfidCommandComboBox,
|
||||
RfidOutputListBox = rfidOutputListBox
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UserControl_Load(object sender, EventArgs e)
|
||||
{
|
||||
this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
|
||||
}
|
||||
|
||||
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
//OnHandleDestroyed(new EventArgs());
|
||||
Ctrl.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.common
|
||||
{
|
||||
public static class HexFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Byte to hex string.
|
||||
/// Formats a single byte as 0xNN.
|
||||
/// Example: 0x0D
|
||||
/// </summary>
|
||||
public static string ToHex(byte value)
|
||||
{
|
||||
return "0x" + value.ToString("X2");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// int to byte - securely
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public static byte ToHexByte(int value)
|
||||
{
|
||||
if (value < 0 || value > 255)
|
||||
throw new ArgumentOutOfRangeException(nameof(value),
|
||||
"Value must be between 0 and 255.");
|
||||
|
||||
return (byte)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a byte array as 0xNN 0xNN ...
|
||||
/// </summary>
|
||||
public static string ToHex(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return "<empty>";
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(' ');
|
||||
|
||||
sb.Append("0x");
|
||||
sb.Append(data[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a byte array exactly as shown in serial terminals.
|
||||
/// Example: "0D 04 08 01 00 1A"
|
||||
/// </summary>
|
||||
public static string ToSerialHex(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(' ');
|
||||
|
||||
sb.Append(data[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string ToHexWithAscii(byte value)
|
||||
{
|
||||
char c = (value >= 32 && value <= 126) ? (char)value : '.';
|
||||
return $"0x{value:X2} ('{c}')";
|
||||
}
|
||||
|
||||
public static string ToSerialHexWithAscii(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var hex = new StringBuilder(data.Length * 3);
|
||||
var ascii = new StringBuilder(data.Length);
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
hex.Append(b.ToString("X2")).Append(' ');
|
||||
|
||||
// Printable ASCII range
|
||||
if (b >= 32 && b <= 126)
|
||||
{
|
||||
ascii.Append((char)b);
|
||||
}
|
||||
// Binary numbers 0–9 -> show digit
|
||||
else if (b <= 9)
|
||||
{
|
||||
ascii.Append((char)('0' + b));
|
||||
}
|
||||
else
|
||||
{
|
||||
ascii.Append('.');
|
||||
}
|
||||
}
|
||||
|
||||
// remove last trailing space in hex
|
||||
if (hex.Length > 0)
|
||||
hex.Length--;
|
||||
|
||||
return $"{hex} | {ascii}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string ToHex(int value)
|
||||
{
|
||||
return $"0x{(byte)value:X2}";
|
||||
}
|
||||
|
||||
public static byte[] IntToBytesBE(int value, int byteCount)
|
||||
{
|
||||
var result = new byte[byteCount];
|
||||
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
result[byteCount - 1 - i] = (byte)(value >> (8 * i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] IntToBytesLE(int value, int byteCount)
|
||||
{
|
||||
var result = new byte[byteCount];
|
||||
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
result[i] = (byte)(value >> (8 * i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] AsciiToBytes(string text)
|
||||
{
|
||||
return string.IsNullOrEmpty(text)
|
||||
? Array.Empty<byte>()
|
||||
: System.Text.Encoding.ASCII.GetBytes(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a hex string to a byte array.
|
||||
/// Like: string hex = "3F 76 65 72 73 3A 20 48 61 72 72 79 20 54 3A 42 38 30 30 2C 20";
|
||||
/// </summary>
|
||||
/// <param name="hex"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static byte[] HexStringToByteArray(string hex)
|
||||
{
|
||||
if (hex == null)
|
||||
throw new ArgumentNullException(nameof(hex));
|
||||
|
||||
return hex
|
||||
.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(b => byte.Parse(b, NumberStyles.HexNumber, CultureInfo.InvariantCulture))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2021 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Protocols.StreamingProtocol;
|
||||
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.common
|
||||
{
|
||||
public enum OptoTelegramFlags : byte
|
||||
{
|
||||
OK = 0,
|
||||
OK_TestStart,
|
||||
OK_TestEnd,
|
||||
InvalidTelegram, /// Wrong telegram format of checksum error
|
||||
SyncError,
|
||||
}
|
||||
|
||||
public class OptoTelegramRaw
|
||||
{
|
||||
public static readonly int Length = 42;
|
||||
private static CultureInfo culture;
|
||||
|
||||
|
||||
///
|
||||
/// Strobed value
|
||||
///
|
||||
public static decimal TestStartTimestampDec;
|
||||
|
||||
///
|
||||
/// Stored values
|
||||
///
|
||||
public OptoTelegramFlags Flags;
|
||||
|
||||
public DateTime DateTime;
|
||||
|
||||
/// From PC
|
||||
public float RefFlow;
|
||||
|
||||
/// [m3/h]
|
||||
public int Counter;
|
||||
|
||||
public Int32 EmfRaw;
|
||||
|
||||
/// Signed EMF from iPerl opto data
|
||||
public Int16 MagneticFieldRaw;
|
||||
|
||||
public Int16 FlowRaw;
|
||||
public double VolumeRaw;
|
||||
public double VolumeRawExt;
|
||||
public Int16 Impedance;
|
||||
public double Timestamp;
|
||||
public double TimestampExt;
|
||||
public byte CheckSum;
|
||||
public int iChannel = -1;
|
||||
|
||||
public int IChannel()
|
||||
{
|
||||
return iChannel;
|
||||
}
|
||||
|
||||
///
|
||||
/// Calculated values
|
||||
///
|
||||
public double EMF()
|
||||
{
|
||||
return 0.000000333 * (double)EmfRaw;
|
||||
}
|
||||
|
||||
public double MagneticField()
|
||||
{
|
||||
return (double)MagneticFieldRaw;
|
||||
}
|
||||
|
||||
public double Flow(double scalingFactor)
|
||||
{
|
||||
return 0.225 * scalingFactor * (double)FlowRaw;
|
||||
}
|
||||
|
||||
public double Volume(double scalingFactor)
|
||||
{
|
||||
return 0.0000625 * scalingFactor * (double)VolumeRawExt;
|
||||
}
|
||||
|
||||
public Int32 FlipTime()
|
||||
{
|
||||
return Impedance;
|
||||
}
|
||||
|
||||
public decimal TimestampDec()
|
||||
{
|
||||
return (decimal)TimestampExt / (decimal)8192;
|
||||
}
|
||||
|
||||
public double VolumeDelta(double scalingFactor, OptoTelegramRaw previous)
|
||||
{
|
||||
return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor);
|
||||
}
|
||||
|
||||
public decimal TimeDelta()
|
||||
{
|
||||
return TimestampDec() - TestStartTimestampDec;
|
||||
}
|
||||
|
||||
public string Label()
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.OK_TestStart) return "#### start test ####";
|
||||
else if (Flags == OptoTelegramFlags.OK_TestEnd) return "#### end of test ####";
|
||||
else return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
static OptoTelegramRaw()
|
||||
{
|
||||
culture = CultureInfo.CreateSpecificCulture("DE"); /// This is to use comma as decimal number separator
|
||||
}
|
||||
|
||||
public OptoTelegramRaw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -------- TIMESTAMP (seconds) --------
|
||||
private const double TS_RANGE = StreamingDecoder.CpuTimeOverflowS;
|
||||
|
||||
// -------- VOLUME (liters) --------
|
||||
private const double VOL_RANGE = StreamingDecoder.DefaultAccuDutOverflowVolumeCm * 1000;
|
||||
|
||||
/// <summary>
|
||||
/// update data by CalibrationRecord
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="counter"></param>
|
||||
/// <param name="refFlow"></param>
|
||||
/// <param name="volumeRawExtLast"></param>
|
||||
/// <param name="timestampExtLast"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void UpdateFromSmart(
|
||||
CalibrationRecord data,
|
||||
int counter,
|
||||
float refFlow,
|
||||
ref double volumeRawExtLast,
|
||||
ref double timestampExtLast)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
UpdateData( data.Channel, data.VolumeCm, data.TimeS, counter, refFlow, ref volumeRawExtLast, ref timestampExtLast);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /// update data by FlowTestRecord
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="counter"></param>
|
||||
/// <param name="refFlow"></param>
|
||||
/// <param name="volumeRawExtLast"></param>
|
||||
/// <param name="timestampExtLast"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void UpdateFromSmart(
|
||||
FlowTestRecord data,
|
||||
int counter,
|
||||
float refFlow,
|
||||
ref double volumeRawExtLast,
|
||||
ref double timestampExtLast)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
UpdateData( data.Channel, data.VolumeCm, data.TimeS, counter, refFlow, ref volumeRawExtLast, ref timestampExtLast);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// update data by OptoTelegramRaw
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="volumeCm"></param>
|
||||
/// <param name="timeS"></param>
|
||||
/// <param name="counter"></param>
|
||||
/// <param name="refFlow"></param>
|
||||
/// <param name="volumeRawExtLast"></param>
|
||||
/// <param name="timestampExtLast"></param>
|
||||
private void UpdateData(
|
||||
int channel,
|
||||
double volumeCm,
|
||||
double timeS,
|
||||
int counter,
|
||||
float refFlow,
|
||||
ref double volumeRawExtLast,
|
||||
ref double timestampExtLast)
|
||||
{
|
||||
iChannel = channel - 1;
|
||||
DateTime = DateTime.Now;
|
||||
Counter = counter;
|
||||
RefFlow = refFlow;
|
||||
Flags = OptoTelegramFlags.OK;
|
||||
|
||||
FlowRaw = 0;
|
||||
VolumeRaw = volumeCm * 1000.0; // liters
|
||||
CheckSum = 0;
|
||||
Impedance = 0;
|
||||
EmfRaw = 0;
|
||||
MagneticFieldRaw = 0;
|
||||
|
||||
double ts = NormalizeTimestamp(timeS);
|
||||
Timestamp = ts;
|
||||
|
||||
VolumeRawExt = UnwrapVolume(VolumeRaw, ref volumeRawExtLast);
|
||||
TimestampExt = UnwrapTimestamp(ts, ref timestampExtLast);
|
||||
}
|
||||
|
||||
private static double NormalizeTimestamp(double timeS)
|
||||
{
|
||||
double ts = timeS % TS_RANGE;
|
||||
if (ts < 0)
|
||||
ts += TS_RANGE;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
private static double UnwrapVolume(double currentVolume, ref double volumeRawExtLast)
|
||||
{
|
||||
double result;
|
||||
|
||||
if (double.IsNaN(volumeRawExtLast))
|
||||
{
|
||||
result = currentVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = currentVolume < volumeRawExtLast
|
||||
? currentVolume + VOL_RANGE
|
||||
: currentVolume;
|
||||
}
|
||||
|
||||
volumeRawExtLast = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static double UnwrapTimestamp(double currentTimestamp, ref double timestampExtLast)
|
||||
{
|
||||
double result;
|
||||
|
||||
if (double.IsNaN(timestampExtLast))
|
||||
{
|
||||
result = currentTimestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
double lastMod = timestampExtLast % TS_RANGE;
|
||||
if (lastMod < 0)
|
||||
lastMod += TS_RANGE;
|
||||
|
||||
double delta = currentTimestamp - lastMod;
|
||||
|
||||
if (delta < -TS_RANGE / 2.0)
|
||||
delta += TS_RANGE;
|
||||
else if (delta > TS_RANGE / 2.0)
|
||||
delta -= TS_RANGE;
|
||||
|
||||
result = timestampExtLast + delta;
|
||||
}
|
||||
|
||||
timestampExtLast = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Alternative to UpdateFromString(...) when data are flushed
|
||||
/// </summary>
|
||||
public bool UpdateFromStringDummy(string telegram)
|
||||
{
|
||||
DateTime = DateTime.Now;
|
||||
RefFlow = 0;
|
||||
|
||||
if ((telegram == null) || (telegram.Length < Length) ||
|
||||
(telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') ||
|
||||
(telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') ||
|
||||
(telegram[40] != '\r') || (telegram[41] != '\n'))
|
||||
{
|
||||
Flags = OptoTelegramFlags.InvalidTelegram;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture,
|
||||
out CheckSum);
|
||||
|
||||
byte calculatedCheckSum = 0;
|
||||
for (int i = 0; i < Length - 4; i++)
|
||||
{
|
||||
calculatedCheckSum += (byte)telegram[i];
|
||||
}
|
||||
|
||||
bool allOk = f7 && (calculatedCheckSum == CheckSum);
|
||||
|
||||
Flags = allOk ? OptoTelegramFlags.OK : OptoTelegramFlags.InvalidTelegram;
|
||||
|
||||
return allOk;
|
||||
}
|
||||
|
||||
|
||||
public void SetFlags(OptoTelegramFlags flags)
|
||||
{
|
||||
this.Flags = flags;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(double scalingFactor, OptoTelegramRaw previous)
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.SyncError)
|
||||
{
|
||||
return "Sychronization error";
|
||||
}
|
||||
else if (Flags == OptoTelegramFlags.InvalidTelegram)
|
||||
{
|
||||
return "Invalid telegram";
|
||||
}
|
||||
else /// if (flags == OptoTelegramFlags.OK / OptoTelegramFlags.OK_TestStart / OptoTelegramFlags.OK_TestEnd)
|
||||
{
|
||||
return string.Format(
|
||||
"{0}:{1}:{2}.{3}\t{4} :\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}\t{17}\t{18}\t{19}\t{20}\t{21}\t{22}",
|
||||
DateTime.Hour.ToString("D2"),
|
||||
DateTime.Minute.ToString("D2"),
|
||||
DateTime.Second.ToString("D2"),
|
||||
DateTime.Millisecond.ToString("D4"),
|
||||
Counter,
|
||||
(EmfRaw & 0x00FFFFFF).ToString("X6"),
|
||||
MagneticFieldRaw.ToString("X4"),
|
||||
FlowRaw.ToString("X4"),
|
||||
((int)VolumeRaw).ToString("X6"),
|
||||
Impedance.ToString("X4"),
|
||||
((int)Timestamp).ToString("X8"),
|
||||
CheckSum.ToString("X2"),
|
||||
EMF().ToString("F4", culture),
|
||||
MagneticField().ToString("F0", culture),
|
||||
Flow(scalingFactor).ToString("F2", culture),
|
||||
Volume(scalingFactor).ToString("F4", culture),
|
||||
FlipTime().ToString("F0", culture),
|
||||
TimestampDec().ToString("F4", culture),
|
||||
(RefFlow * 1000).ToString("F2", culture),
|
||||
VolumeDelta(scalingFactor, previous).ToString("F4", culture),
|
||||
TimeDelta().ToString("F3", culture),
|
||||
scalingFactor.ToString("F1", culture),
|
||||
Label());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
|
||||
{
|
||||
public class ChannelAverages
|
||||
{
|
||||
public double?[] VolumeStart { get; } = new double?[3];
|
||||
public double?[] VolumeEnd { get; } = new double?[3];
|
||||
public double?[] TimeStart { get; } = new double?[3];
|
||||
public double?[] TimeEnd { get; } = new double?[3];
|
||||
|
||||
public static double Average(double?[] values)
|
||||
{
|
||||
double sum = 0;
|
||||
int count = 0;
|
||||
|
||||
foreach (var v in values)
|
||||
{
|
||||
if (v.HasValue)
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count > 0 ? sum / count : 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications
|
||||
{
|
||||
/// <summary>
|
||||
/// describe a genesis register.
|
||||
/// need for read and write
|
||||
/// all request protocols uses RegisterDefinition
|
||||
/// </summary>
|
||||
public class ApplicationDefinition
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// name of the application
|
||||
/// </summary>
|
||||
public String AppName;
|
||||
|
||||
/// <summary>
|
||||
/// address of application
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Aug-05" author="Thomas Wiedebusch">
|
||||
/// - AppId from Byte to UInt16 including typecast for Byte[] return. To external, it will be used as Byte
|
||||
/// as before this change. But being able to parse the configuration.json with OPTICALINTERFACE using the
|
||||
/// AppId 256, which exceeds the byte range as this isn't a real application, but will be used to identify
|
||||
/// the interface (configuration.json) version.
|
||||
/// </remarks>
|
||||
public UInt16 AppId;
|
||||
|
||||
/// <summary>
|
||||
/// version of the application
|
||||
/// </summary>
|
||||
public Int32? AppVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Get application name
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public String GetIdent()
|
||||
{
|
||||
return $"{AppName}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications.Const
|
||||
{
|
||||
/// <summary>
|
||||
/// Genesis meter application state
|
||||
/// </summary>
|
||||
public enum MeterAppState
|
||||
{
|
||||
/// <summary>
|
||||
/// This file application is not installed in the meter
|
||||
/// </summary>
|
||||
MeterAppNotInstalled,
|
||||
/// <summary>
|
||||
/// Meter version is equal to file version - it is up to date
|
||||
/// </summary>
|
||||
MeterAppUpToDate,
|
||||
/// <summary>
|
||||
/// Installation of application is required
|
||||
/// </summary>
|
||||
MeterAppInstallationRequired,
|
||||
/// <summary>
|
||||
/// Meter application is different from file application
|
||||
/// </summary>
|
||||
MeterAppVersionOutdated,
|
||||
/// <summary>
|
||||
/// CRC does not match even if meter and file application version are
|
||||
/// shown as being identical!
|
||||
/// </summary>
|
||||
InvalidCrc,
|
||||
/// <summary>
|
||||
/// Meter applications has to be erased
|
||||
/// </summary>
|
||||
MeterAppErasureRequired,
|
||||
/// <summary>
|
||||
/// Application successfully downloaded to meter
|
||||
/// </summary>
|
||||
MeterAppDownloadSucceeded,
|
||||
/// <summary>
|
||||
/// Application download to meter suspicious
|
||||
/// </summary>
|
||||
MeterAppDownloadSuspicious,
|
||||
/// <summary>
|
||||
/// Application successfully erased from meter
|
||||
/// </summary>
|
||||
MeterAppSuccessfulErased,
|
||||
/// <summary>
|
||||
/// Application successfully updated in meter
|
||||
/// </summary>
|
||||
MeterAppSuccessfulUpdated,
|
||||
/// <summary>
|
||||
/// Application download to meter failed
|
||||
/// </summary>
|
||||
MeterAppDownloadFailed,
|
||||
/// <summary>
|
||||
/// Application download to meter active ongoing
|
||||
/// </summary>
|
||||
MeterAppDownloadActive,
|
||||
/// <summary>
|
||||
/// This file application is invalid
|
||||
/// </summary>
|
||||
FileAppInvalid,
|
||||
/// <summary>
|
||||
/// State is unknown because package file not loaded
|
||||
/// </summary>
|
||||
Unknown,
|
||||
/// <summary>
|
||||
/// Meter application detected but not checked
|
||||
/// </summary>
|
||||
MeterAppInstalledUnchecked,
|
||||
/// <summary>
|
||||
/// Meter application is not required
|
||||
/// </summary>
|
||||
MeterAppNotRequired,
|
||||
/// <summary>
|
||||
/// Delimiter for list
|
||||
/// </summary>
|
||||
MeterAppStateListDelimiter
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications.Const
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation of state and string
|
||||
/// </summary>
|
||||
public class MeterAppStateInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Build state information
|
||||
/// </summary>
|
||||
private readonly MeterAppStateText[] _stateInfos;
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
public MeterAppStateInfo()
|
||||
{
|
||||
_stateInfos = new MeterAppStateText[(Int32)MeterAppState.MeterAppStateListDelimiter];
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppNotInstalled].State = MeterAppState.MeterAppNotInstalled;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppNotInstalled].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppNotInstalled;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppNotRequired].State = MeterAppState.MeterAppNotRequired;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppNotRequired].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppNotRequired;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppUpToDate].State = MeterAppState.MeterAppUpToDate;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppUpToDate].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppUpToDate;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppInstallationRequired].State = MeterAppState.MeterAppInstallationRequired;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppInstallationRequired].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppInstallationRequired;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppVersionOutdated].State = MeterAppState.MeterAppVersionOutdated;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppVersionOutdated].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppVersionOutdated;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.InvalidCrc].State = MeterAppState.InvalidCrc;
|
||||
_stateInfos[(Int32)MeterAppState.InvalidCrc].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrInvalidCrc;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppErasureRequired].State = MeterAppState.MeterAppErasureRequired;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppErasureRequired].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppErasureRequired;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadSucceeded].State = MeterAppState.MeterAppDownloadSucceeded;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadSucceeded].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppDownloadSucceeded;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadSuspicious].State = MeterAppState.MeterAppDownloadSuspicious;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadSuspicious].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppDownloadSuspicious;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppSuccessfulErased].State = MeterAppState.MeterAppSuccessfulErased;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppSuccessfulErased].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppSuccessfulErased;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppSuccessfulUpdated].State = MeterAppState.MeterAppSuccessfulUpdated;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppSuccessfulUpdated].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppSuccessfulUpdated;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadFailed].State = MeterAppState.MeterAppDownloadFailed;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadFailed].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppDownloadFailed;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadActive].State = MeterAppState.MeterAppDownloadActive;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppDownloadActive].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppDownloadActive;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.FileAppInvalid].State = MeterAppState.FileAppInvalid;
|
||||
_stateInfos[(Int32)MeterAppState.FileAppInvalid].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrFileAppInvalid;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.Unknown].State = MeterAppState.Unknown;
|
||||
_stateInfos[(Int32)MeterAppState.Unknown].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppStateUnknown;
|
||||
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppInstalledUnchecked].State = MeterAppState.MeterAppInstalledUnchecked;
|
||||
_stateInfos[(Int32)MeterAppState.MeterAppInstalledUnchecked].Message = Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources.StrMeterAppDetected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of this state
|
||||
/// </summary>
|
||||
/// <param name="state">state to search for information text</param>
|
||||
public String GetTextFromState(MeterAppState state)
|
||||
{
|
||||
return (from stateInfo in _stateInfos
|
||||
where stateInfo.State == state select stateInfo.Message).Last();
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the state of the text
|
||||
/// </summary>
|
||||
/// <param name="text">information text to search if state is assigned</param>
|
||||
public MeterAppState GetStateFromText(String text)
|
||||
{
|
||||
return (from stateInfo in _stateInfos
|
||||
where stateInfo.Message == text select stateInfo.State).Last();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications.Const
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation between meter application state and text
|
||||
/// </summary>
|
||||
public struct MeterAppStateText
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of the firmware update
|
||||
/// </summary>
|
||||
public MeterAppState State;
|
||||
/// <summary>
|
||||
/// The message text of the meter application state
|
||||
/// </summary>
|
||||
public String Message;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications
|
||||
{
|
||||
/// <summary>
|
||||
/// File FW and application information
|
||||
/// </summary>
|
||||
public class FileApplications
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of application
|
||||
/// </summary>
|
||||
public String AppName;
|
||||
|
||||
/// <summary>
|
||||
/// File name of the file system where the binaries are stored
|
||||
/// </summary>
|
||||
public String BinaryFilename;
|
||||
|
||||
/// <summary>
|
||||
/// File name of the meter including the "1\\upg" string and the AppId as hexadecimal 2 digits
|
||||
/// </summary>
|
||||
public String MeterFilename;
|
||||
|
||||
/// <summary>
|
||||
/// Ctor file applications
|
||||
/// </summary>
|
||||
/// <param name="binaryFilename"></param>
|
||||
public FileApplications(String binaryFilename)
|
||||
{
|
||||
BinaryFilename = binaryFilename;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identification number of application
|
||||
/// </summary>
|
||||
public Byte AppId;
|
||||
|
||||
/// <summary>
|
||||
/// Version of application
|
||||
/// </summary>
|
||||
public UInt32 Version;
|
||||
|
||||
/// <summary>
|
||||
/// Version string of application because of FLEXNETVERSION
|
||||
/// does return a different layout, instead of decimals it
|
||||
/// used hexadecimals. Therefore the version has to be saved as
|
||||
/// string at time of receiving for the FW-Update comparison
|
||||
/// </summary>
|
||||
public String StrVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Check of application for verification
|
||||
/// </summary>
|
||||
public UInt16 Crc;
|
||||
|
||||
/// <summary>
|
||||
/// Validation of application
|
||||
/// </summary>
|
||||
public Boolean IsValid;
|
||||
|
||||
/// <summary>
|
||||
/// Binary file content
|
||||
/// </summary>
|
||||
public List<Byte> BinData = new List<Byte>();
|
||||
|
||||
/// <summary>
|
||||
/// Actual part if file is going to be partitioned
|
||||
/// </summary>
|
||||
public Int32 Part = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Number of parts for entire file if partitioned
|
||||
/// </summary>
|
||||
public Int32 Parts = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Meter file offset if file is partitioned
|
||||
/// </summary>
|
||||
public Int32 MeterFileOffset = 0;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications.Const;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Meter FW and application information
|
||||
/// </summary>
|
||||
public class MeterApplications
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of application
|
||||
/// </summary>
|
||||
public String AppName;
|
||||
|
||||
/// <summary>
|
||||
/// Identification number of application
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Aug-05" author="Thomas Wiedebusch">
|
||||
/// - AppId from Byte to UInt16 including typecast for Byte[] return. To external, it will be used as Byte
|
||||
/// as before this change. But being able to parse the configuration.json with OPTICALINTERFACE using the
|
||||
/// AppId 256, which exceeds the byte range as this isn't a real application, but will be used to identify
|
||||
/// the interface (configuration.json) version.
|
||||
/// </remarks>
|
||||
public UInt16 AppId;
|
||||
|
||||
/// <summary>
|
||||
/// Version of application
|
||||
/// </summary>
|
||||
public UInt32 Version;
|
||||
|
||||
/// <summary>
|
||||
/// Version string of application because of FLEXNETVERSION does return a different layout, instead of decimals
|
||||
/// it uses hexadecimals. Therefore, the version has to be saved as string at time of receiving for the FW-Update
|
||||
/// comparison.
|
||||
/// </summary>
|
||||
public String StrVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Check of application for verification
|
||||
/// </summary>
|
||||
public UInt16 Crc;
|
||||
|
||||
/// <summary>
|
||||
/// Check if application is installed
|
||||
/// </summary>
|
||||
public Boolean IsInstalled;
|
||||
|
||||
/// <summary>
|
||||
/// Update this version
|
||||
/// </summary>
|
||||
public Boolean Update;
|
||||
|
||||
/// <summary>
|
||||
/// Erase this version
|
||||
/// </summary>
|
||||
public Boolean Erase;
|
||||
|
||||
/// <summary>
|
||||
/// Status text
|
||||
/// </summary>
|
||||
public MeterAppState Status;
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to INVALID UPDATE FILE.
|
||||
/// </summary>
|
||||
public static string StrFileAppInvalid {
|
||||
get {
|
||||
return ResourceManager.GetString("StrFileAppInvalid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CRC ERROR.
|
||||
/// </summary>
|
||||
public static string StrInvalidCrc {
|
||||
get {
|
||||
return ResourceManager.GetString("StrInvalidCrc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installed.
|
||||
/// </summary>
|
||||
public static string StrMeterAppDetected {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppDetected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to DOWNLOAD....
|
||||
/// </summary>
|
||||
public static string StrMeterAppDownloadActive {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppDownloadActive", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Download failed.
|
||||
/// </summary>
|
||||
public static string StrMeterAppDownloadFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppDownloadFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Burn - Trigger upgrade required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppDownloadSucceeded {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppDownloadSucceeded", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verification required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppDownloadSuspicious {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppDownloadSuspicious", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Erase - Trigger upgrade required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppErasureRequired {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppErasureRequired", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installation required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppInstallationRequired {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppInstallationRequired", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not installed.
|
||||
/// </summary>
|
||||
public static string StrMeterAppNotInstalled {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppNotInstalled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppNotRequired {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppNotRequired", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installation state unknown.
|
||||
/// </summary>
|
||||
public static string StrMeterAppStateUnknown {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppStateUnknown", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Erasure succeeded.
|
||||
/// </summary>
|
||||
public static string StrMeterAppSuccessfulErased {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppSuccessfulErased", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Update succeeded.
|
||||
/// </summary>
|
||||
public static string StrMeterAppSuccessfulUpdated {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppSuccessfulUpdated", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Okay.
|
||||
/// </summary>
|
||||
public static string StrMeterAppUpToDate {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppUpToDate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Update required.
|
||||
/// </summary>
|
||||
public static string StrMeterAppVersionOutdated {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterAppVersionOutdated", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="StrMeterAppNotInstalled" xml:space="preserve">
|
||||
<value>Nicht installiert</value>
|
||||
</data>
|
||||
<data name="StrMeterAppUpToDate" xml:space="preserve">
|
||||
<value>Okay</value>
|
||||
</data>
|
||||
<data name="StrMeterAppInstallationRequired" xml:space="preserve">
|
||||
<value>Installation notwendig</value>
|
||||
</data>
|
||||
<data name="StrMeterAppVersionOutdated" xml:space="preserve">
|
||||
<value>Update erforderlich</value>
|
||||
</data>
|
||||
<data name="StrInvalidCrc" xml:space="preserve">
|
||||
<value>Prüfsummenfehler (CRC)</value>
|
||||
</data>
|
||||
<data name="StrMeterAppErasureRequired" xml:space="preserve">
|
||||
<value>Lösche beim Abschlußvorgang</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadSucceeded" xml:space="preserve">
|
||||
<value>Übernehme beim Abschlußvorgang</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadSuspicious" xml:space="preserve">
|
||||
<value>Überprüfung notwendig</value>
|
||||
</data>
|
||||
<data name="StrMeterAppSuccessfulErased" xml:space="preserve">
|
||||
<value>Löschen erforderlich</value>
|
||||
</data>
|
||||
<data name="StrMeterAppSuccessfulUpdated" xml:space="preserve">
|
||||
<value>Aktualisierung war erfolgreich</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadFailed" xml:space="preserve">
|
||||
<value>Dateiübertragung fehlgeschlagen</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadActive" xml:space="preserve">
|
||||
<value>EINSPIELEN...</value>
|
||||
</data>
|
||||
<data name="StrFileAppInvalid" xml:space="preserve">
|
||||
<value>Ungültige Aktualisierungsdatei</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDetected" xml:space="preserve">
|
||||
<value>Installiert</value>
|
||||
</data>
|
||||
<data name="StrMeterAppStateUnknown" xml:space="preserve">
|
||||
<value>Installationszustand unbekannt</value>
|
||||
</data>
|
||||
<data name="StrMeterAppNotRequired" xml:space="preserve">
|
||||
<value>Nicht eforderlich</value>
|
||||
</data>
|
||||
</root>
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="StrMeterAppNotInstalled" xml:space="preserve">
|
||||
<value>Not installed</value>
|
||||
</data>
|
||||
<data name="StrMeterAppUpToDate" xml:space="preserve">
|
||||
<value>Okay</value>
|
||||
</data>
|
||||
<data name="StrMeterAppInstallationRequired" xml:space="preserve">
|
||||
<value>Installation required</value>
|
||||
</data>
|
||||
<data name="StrMeterAppVersionOutdated" xml:space="preserve">
|
||||
<value>Update required</value>
|
||||
</data>
|
||||
<data name="StrInvalidCrc" xml:space="preserve">
|
||||
<value>CRC ERROR</value>
|
||||
</data>
|
||||
<data name="StrMeterAppErasureRequired" xml:space="preserve">
|
||||
<value>Erase - Trigger upgrade required</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadSucceeded" xml:space="preserve">
|
||||
<value>Burn - Trigger upgrade required</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadSuspicious" xml:space="preserve">
|
||||
<value>Verification required</value>
|
||||
</data>
|
||||
<data name="StrMeterAppSuccessfulErased" xml:space="preserve">
|
||||
<value>Erasure succeeded</value>
|
||||
</data>
|
||||
<data name="StrMeterAppSuccessfulUpdated" xml:space="preserve">
|
||||
<value>Update succeeded</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadFailed" xml:space="preserve">
|
||||
<value>Download failed</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDownloadActive" xml:space="preserve">
|
||||
<value>DOWNLOAD...</value>
|
||||
</data>
|
||||
<data name="StrFileAppInvalid" xml:space="preserve">
|
||||
<value>INVALID UPDATE FILE</value>
|
||||
</data>
|
||||
<data name="StrMeterAppDetected" xml:space="preserve">
|
||||
<value>Installed</value>
|
||||
</data>
|
||||
<data name="StrMeterAppStateUnknown" xml:space="preserve">
|
||||
<value>Installation state unknown</value>
|
||||
</data>
|
||||
<data name="StrMeterAppNotRequired" xml:space="preserve">
|
||||
<value>Not required</value>
|
||||
</data>
|
||||
</root>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for inter-program exchange
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker for lack of information in strings e.g. for region, size, LutCrc, ...
|
||||
/// </summary>
|
||||
public const String StrUnknown = "?";
|
||||
/// <summary>
|
||||
/// Marker for wildcard in search operations
|
||||
/// </summary>
|
||||
public const String StrWildcard = "*";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for CRC16 CCITT calculation
|
||||
/// </summary>
|
||||
public static class Crc16Ccitt
|
||||
{
|
||||
/// <summary>
|
||||
/// Initial CRC value
|
||||
/// </summary>
|
||||
private const UInt16 CrcSeedFfff = 0xFFFF;
|
||||
/// <summary>
|
||||
/// Initial CRC value
|
||||
/// </summary>
|
||||
private const UInt16 CrcSeed3791 = 0x3791;
|
||||
|
||||
/// <summary>
|
||||
/// Generator polynomial MagFlux - Modbus RTU
|
||||
/// </summary>
|
||||
private const UInt16 CrcGpA001 = 0xA001;
|
||||
/// <summary>
|
||||
/// Generator polynomial GENESIS
|
||||
/// </summary>
|
||||
private const UInt16 CrcGp1021 = 0x1021;
|
||||
|
||||
/// <summary>
|
||||
/// Generator polynomial RFID
|
||||
/// </summary>
|
||||
private const UInt16 CrcGp0408 = 0x0408;
|
||||
|
||||
/// <summary>
|
||||
/// Generator polynomial for reversed IrDA
|
||||
/// </summary>
|
||||
private const UInt16 CrcGp8408 = 0x8408;
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC (LSB first, reversed, CRC CCITT 0x8408) from a data array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="data">data to be processed</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateReversedLsb8408(Byte[] data)
|
||||
{
|
||||
var crc = CrcSeedFfff;
|
||||
foreach (var t in data)
|
||||
{
|
||||
//copy data byte to lower word because of LSB will be XORed
|
||||
var dataWord = (UInt16)(t & 0x00FF);
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
//test if CRC lowest bit is XORed set to one
|
||||
if (0x0001 == ((crc ^ dataWord) & 0x0001))
|
||||
{
|
||||
crc >>= 1;
|
||||
//apply generator polynomial
|
||||
crc ^= CrcGp8408;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
|
||||
dataWord >>= 1;
|
||||
}
|
||||
}
|
||||
return ((UInt16)~crc);
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculates the bitwise inverted CRC (MSB first, CRCCCITT 0x1021)
|
||||
/// from a data array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="data">data to be processed</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateInvertedMsb1021(Byte[] data)
|
||||
{
|
||||
return (UInt16)~CalculateMsb1021(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the Modbus RTU CRC (LSB first, CRCCCITT 0xA001)
|
||||
/// from a data array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="data">data to be processed</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 ModbusRtuLsbA001(Byte[] data)
|
||||
{
|
||||
var crc = CrcSeedFfff;
|
||||
|
||||
for (var t = 0; t < data.Length; t++)
|
||||
{
|
||||
crc ^= data[t]; // XOR byte into least sig. byte of crc
|
||||
|
||||
for (var i = 8; i != 0; i--)
|
||||
{
|
||||
if ((crc & 0x0001) != 0)
|
||||
{
|
||||
crc >>= 1;
|
||||
crc ^= CrcGpA001;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC (MSB first, CRCCCITT 0x1021) from a data array of bytes.
|
||||
/// <para>18.07.2024 - optional parameters start and length added - for more flexibility by calculating a CRC of a message.</para>
|
||||
/// <para>18.07.2024 - length checks: if length less or equal 0 or grater than the data length: the data length is taken as length.</para>
|
||||
/// </summary>
|
||||
/// <param name="start">optional, default = 0</param>
|
||||
/// <param name="length">optional, default = 0</param>
|
||||
/// <param name="data">data to be processed</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateMsb1021(Byte[] data, Int32 start = 0, Int32 length = 0)
|
||||
{
|
||||
var dataLength = data.Length;
|
||||
|
||||
if (length <= 0 || length > dataLength)
|
||||
{
|
||||
length = dataLength;
|
||||
}
|
||||
|
||||
var crc = CrcSeedFfff;
|
||||
|
||||
for (var b = start; b < length; b++)
|
||||
{
|
||||
var t = data[b];
|
||||
|
||||
//copy data byte to higher word because of MSB will be XORed
|
||||
var dataWord = (UInt16)((t << 8) & 0xFF00);
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
//test if CRC highest bit or data input highest bit is XORed set to one
|
||||
if (0x8000 == ((crc ^ dataWord) & 0x8000)) //shifted in MSB first
|
||||
{
|
||||
//shift CRC high bit out
|
||||
crc <<= 1;
|
||||
//apply generator polynomial
|
||||
crc ^= CrcGp1021;
|
||||
}
|
||||
else //CRC highest bit and data input highest bit is equal
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
dataWord <<= 1; //MSB first shifted out
|
||||
}
|
||||
}
|
||||
//foreach (var t in data)
|
||||
//{
|
||||
// //copy data byte to higher word because of MSB will be XORed
|
||||
// var dataWord = (UInt16)((t << 8) & 0xFF00);
|
||||
// for (var i = 0; i < 8; i++)
|
||||
// {
|
||||
// //test if CRC highest bit or data input highest bit is XORed set to one
|
||||
// if (0x8000 == ((crc ^ dataWord) & 0x8000)) //shifted in MSB first
|
||||
// {
|
||||
// //shift CRC high bit out
|
||||
// crc <<= 1;
|
||||
// //apply generator polynomial
|
||||
// crc ^= CrcGp1021;
|
||||
// }
|
||||
// else //CRC highest bit and data input highest bit is equal
|
||||
// {
|
||||
// crc <<= 1;
|
||||
// }
|
||||
// dataWord <<= 1; //MSB first shifted out
|
||||
// }
|
||||
// }
|
||||
return crc;
|
||||
}
|
||||
|
||||
public static Byte[] CalculateCRC1021LSBFirst(Byte[] bytes, Int32 start, Int32 length)
|
||||
{
|
||||
var crc = CalculateMsb1021(bytes, start, length);
|
||||
|
||||
return BitConverter.GetBytes(crc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC (LSB first, CRCCCITT 0x0408) from a data array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="data">data to be processed</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateLsb0408(Byte[] data)
|
||||
{
|
||||
var crc = CrcSeed3791;
|
||||
foreach (var t in data)
|
||||
{
|
||||
var dataByte = t;
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
//test if CRC lowest bit is set to one
|
||||
if (1 == (crc & 1))
|
||||
{
|
||||
//shift CRC low bit out
|
||||
crc >>= 1;
|
||||
//test lowest bit of data word
|
||||
if (1 == (dataByte & 1))
|
||||
crc |= 0x8000;
|
||||
//invert CRC MSB
|
||||
crc ^= 0x8000;
|
||||
}
|
||||
else //CRC lowest bit not set
|
||||
{
|
||||
//shift CRC low bit out
|
||||
crc >>= 1;
|
||||
//test lowest bit of data word
|
||||
if (1 == (dataByte & 1))
|
||||
crc |= 0x8000;
|
||||
}
|
||||
if (0x8000 == (crc & 0x8000))
|
||||
//apply generator polynomial
|
||||
crc ^= CrcGp0408;
|
||||
|
||||
dataByte >>= 1; //LSB first shifted out
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// abstract for set structure for BaseDataEventArgs
|
||||
/// </summary>
|
||||
public abstract class BaseDataEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 'Base' get event record form real child.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Object GetData()
|
||||
{
|
||||
return GetEventData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get real Event record
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Object GetEventData();
|
||||
|
||||
/// <summary>
|
||||
/// Holds the record before decoding, for logging
|
||||
/// </summary>
|
||||
public String RawData;
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class BendDetectDataEventArgs : BaseDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// new record from Stream
|
||||
/// </summary>
|
||||
public BendDetectionRecord NewData;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetEventData()
|
||||
{
|
||||
return NewData;
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class CalibDataEventArgs : BaseDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Stream record for calibration on channel
|
||||
/// </summary>
|
||||
public CalibrationRecord CalibChl;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetEventData()
|
||||
{
|
||||
return CalibChl;
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class FlowDataEventArgs : BaseDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// new record from Stream
|
||||
/// </summary>
|
||||
public FlowTestRecord NewData;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetEventData()
|
||||
{
|
||||
return NewData;
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class RegisterUpdatedEventArgs : EventArgs
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Ctor with base record
|
||||
/// </summary>
|
||||
/// <param name="register">base record <see cref="F:Register" /></param>
|
||||
/// <param name="value">base record <see cref="F:Value" /></param>
|
||||
public RegisterUpdatedEventArgs(RegisterDefinition register, Byte[] value)
|
||||
{
|
||||
Register = register;
|
||||
Value = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Register witch has updated
|
||||
/// </summary>
|
||||
public RegisterDefinition Register;
|
||||
|
||||
/// <summary>
|
||||
/// New Value in Register
|
||||
/// </summary>
|
||||
public Byte[] Value;
|
||||
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// EventArgs for Request Responses
|
||||
/// </summary>
|
||||
public class RequestResponseDataEventArgs : BaseDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Request response from meter
|
||||
/// </summary>
|
||||
public List<Byte> RequestResponseData;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetEventData()
|
||||
{
|
||||
return RequestResponseData;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Streaming record for protocol M (information about bend detection and correction)
|
||||
/// </summary>
|
||||
public class BendDetectionRecord : MeasurementRecord
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The status of the U0 detection for this measurement
|
||||
/// </summary>
|
||||
public enum StatusBendU0Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// Status okay
|
||||
/// </summary>
|
||||
OKAY = 0,
|
||||
/// <summary>
|
||||
/// Error code as defined by field name
|
||||
/// </summary>
|
||||
ERROR_GENESISFLOW_INSTALLATION_HIGH_TIME_DIFF = 0x0F41,
|
||||
/// <summary>
|
||||
/// Error code as defined by field name
|
||||
/// </summary>
|
||||
ERROR_GENESISFLOW_INSTALLATION_LOW_FLOW_IGNORE = 0x0F42,
|
||||
/// <summary>
|
||||
/// Error code as defined by field name
|
||||
/// </summary>
|
||||
ERROR_GENESISFLOW_INSTALLATION_BAD_CHANNELS = 0x0F43,
|
||||
/// <summary>
|
||||
/// Error code as defined by field name
|
||||
/// </summary>
|
||||
ERROR_GENESISFLOW_INSTALLATION_FIXED = 0x0F44
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An enum describing the installation type detected
|
||||
/// </summary>
|
||||
public enum InstallationTypeEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// Installation type code as defined by field name
|
||||
/// </summary>
|
||||
INSTALLATION_U0_180_360 = 0,
|
||||
/// <summary>
|
||||
/// Installation type code as defined by field name
|
||||
/// </summary>
|
||||
INSTALLATION_U0_90_270 = 1,
|
||||
/// <summary>
|
||||
/// Installation type code as defined by field name
|
||||
/// </summary>
|
||||
INSTALLATION_UNDISTURBED = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Status of U0 Bend detection
|
||||
/// </summary>
|
||||
public StatusBendU0Enum StatusBendU0;
|
||||
|
||||
/// <summary>
|
||||
/// Installation type code
|
||||
/// </summary>
|
||||
public InstallationTypeEnum InstallationType;
|
||||
|
||||
/// <summary>
|
||||
/// The proportion of the installation correction to apply based on the detected
|
||||
/// installation. 100% == 0x8000
|
||||
/// </summary>
|
||||
public Double CorrectionFactor_percent;
|
||||
|
||||
/// <summary>
|
||||
/// The default proportion of the installation correction to apply based on the
|
||||
/// detected installation. 100% == 0x8000
|
||||
/// </summary>
|
||||
private const UInt32 DefaultCorrectionFactor = 0x8000;
|
||||
|
||||
/// <summary>
|
||||
/// Scale for correction factor to apply to convert it to percentage value 100% == 0x8000
|
||||
/// </summary>
|
||||
public const Double CorrectionFactorScale = 100.0 / DefaultCorrectionFactor;
|
||||
|
||||
/// <summary>
|
||||
/// The volume in internal units before correction applied
|
||||
/// </summary>
|
||||
public Double PreCorrectionVolumeRaw;
|
||||
|
||||
/// <summary>
|
||||
/// The volume in internal units after correction applied
|
||||
/// </summary>
|
||||
public Double PostCorrectionVolumeRaw;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get result as string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override String ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append($"Status={StatusBendU0}").Append(",")
|
||||
.Append($"Installation={InstallationType}").Append(",")
|
||||
.Append($"Factor={CorrectionFactor_percent}").Append(",")
|
||||
.Append($"PreVolume={PreCorrectionVolumeRaw}").Append(",")
|
||||
.Append($"PostVolume={PostCorrectionVolumeRaw}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// hold streaming record for protocol H (contains calibration record)
|
||||
/// </summary>
|
||||
public class CalibrationRecord : MeasurementRecord
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// record validation
|
||||
/// </summary>
|
||||
public UInt16 Validation;
|
||||
|
||||
/// <summary>
|
||||
/// total time of flight in seconds
|
||||
/// </summary>
|
||||
public Double TotalTimeOfFlightS;
|
||||
|
||||
/// <summary>
|
||||
/// delta time of flight in seconds
|
||||
/// </summary>
|
||||
public Double DeltaTimeOfFlightS;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// total time of flight in cordonel units
|
||||
/// </summary>
|
||||
public Int32 RawTotalTimeOfFlight;
|
||||
|
||||
/// <summary>
|
||||
/// delta time of flight in cordonel units
|
||||
/// </summary>
|
||||
public Int32 RawDeltaTimeOfFlight;
|
||||
|
||||
/// <summary>
|
||||
/// volume scale (default: 1024) means
|
||||
/// 1024digits = 1ml
|
||||
/// </summary>
|
||||
public Double VolumeScaleRawPerMl;
|
||||
|
||||
/// <summary>
|
||||
/// volume factor to convert raw to m³
|
||||
/// uses 1E-6 (ml to m³) / VolumeScaleRawPerMl
|
||||
/// </summary>
|
||||
public Double VolumeFactorRawToQm;
|
||||
|
||||
/// <summary>
|
||||
/// raw volume between two samples
|
||||
/// </summary>
|
||||
public Double DeltaVolumeRaw;
|
||||
|
||||
/// <summary>
|
||||
/// calculated out of dRawVolume * VolumeFactorRawToQm .
|
||||
/// in cubic meters
|
||||
/// </summary>
|
||||
public Double DeltaVolumeQm;
|
||||
|
||||
/// <summary>
|
||||
/// accumulated raw volume
|
||||
/// </summary>
|
||||
public Double AccuVolumeRaw;
|
||||
|
||||
/// <summary>
|
||||
/// sample interval between two samples in seconds
|
||||
/// </summary>
|
||||
public Double SampleIntervalS;
|
||||
|
||||
/// <summary>
|
||||
/// high threshold amplitude in V
|
||||
/// </summary>
|
||||
public Double AmplitudeUpV;
|
||||
|
||||
/// <summary>
|
||||
/// low threshold amplitude in V
|
||||
/// </summary>
|
||||
public Double AmplitudeDownV;
|
||||
|
||||
/// <summary>
|
||||
/// high ratio for pulse width
|
||||
/// </summary>
|
||||
public Double PulseWidthRatioUp;
|
||||
|
||||
/// <summary>
|
||||
/// low ratio for pulse width
|
||||
/// </summary>
|
||||
public Double PulseWidthRatioDown;
|
||||
|
||||
/// <summary>
|
||||
/// raw temperature
|
||||
/// </summary>
|
||||
public Double TemperatureRaw;
|
||||
|
||||
/// <summary>
|
||||
/// temperature scale
|
||||
/// </summary>
|
||||
public Double TemperaturePowFactor;
|
||||
|
||||
/// <summary>
|
||||
/// calculated temperature in degree C
|
||||
/// </summary>
|
||||
public Double TemperatureDegC;
|
||||
|
||||
/// <summary>
|
||||
/// Get result as string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override String ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append($"Channel={Channel}").Append(",")
|
||||
.Append($"Validation={Validation}").Append(",")
|
||||
.Append($"TotalTimeOfFlightS={TotalTimeOfFlightS}").Append(",")
|
||||
.Append($"DeltaTimeOfFlightS={DeltaTimeOfFlightS}").Append(",")
|
||||
.Append($"DeltaVolumeRaw={DeltaVolumeRaw}").Append(",")
|
||||
|
||||
.Append($"VolumeScaleRawPerMl={VolumeScaleRawPerMl}").Append(",")
|
||||
.Append($"VolumeFactorRawToQm={VolumeFactorRawToQm}").Append(",")
|
||||
.Append($"DeltaVolumeRaw={DeltaVolumeRaw}").Append(",")
|
||||
.Append($"DeltaVolumeQm={DeltaVolumeQm}").Append(",")
|
||||
.Append($"AccuVolumeRaw={AccuVolumeRaw}").Append(",")
|
||||
.Append($"VolumeCm={VolumeCm}").Append(",")
|
||||
.Append($"AccuDutOverflowVolumeCm={OverflowVolumeCm}").Append(",")
|
||||
|
||||
.Append($"SampleIntervalS={SampleIntervalS}").Append(",")
|
||||
.Append($"AmplitudeUpV={AmplitudeUpV}").Append(",")
|
||||
.Append($"AmplitudeDownV={AmplitudeDownV}").Append(",")
|
||||
.Append($"PulseWidthRatioUp={PulseWidthRatioUp}").Append(",")
|
||||
.Append($"PulseWidthRatioDown={PulseWidthRatioDown}").Append(",")
|
||||
|
||||
.Append($"TemperatureRaw={TemperatureRaw}").Append(",")
|
||||
.Append($"TemperaturePowFactor={TemperaturePowFactor}").Append(",")
|
||||
.Append($"TemperatureDegC={TemperatureDegC}").Append(",")
|
||||
|
||||
.Append($"TimeS={TimeS}").Append(",")
|
||||
.Append($"OverflowTimeS={OverflowTimeS}").Append(",")
|
||||
|
||||
.Append($"CRC={Crc}").Append(",")
|
||||
.Append($"IsValid={IsValid}").Append(",")
|
||||
|
||||
.Append($"ReceivedTimeUtc={ReceivedTime}").Append(",")
|
||||
.Append($"DecodedTimeUtc={DecodedTime}").Append(",")
|
||||
.Append($"SyncMarkRecord={SyncMarkRecord}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages.MeasurementRecords
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// struct to hold Led record for protocol F (contains measurement record)
|
||||
/// </summary>
|
||||
public class FlowTestRecord : MeasurementRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Get result as string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override String ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb = sb.Append($"VolumeCm={VolumeCm}").Append(",")
|
||||
.Append($"OverflowVolumeCm={OverflowVolumeCm}").Append(",")
|
||||
.Append($"TimeS={TimeS}").Append(",")
|
||||
.Append($"OverflowTimeS={OverflowTimeS}").Append(",")
|
||||
.Append($"CRC={Crc}").Append(",")
|
||||
.Append($"IsValid={IsValid}").Append(",")
|
||||
.Append($"ReceivedTimeUtc={ReceivedTime}").Append(",")
|
||||
.Append($"DecodedTimeUtc={DecodedTime}").Append(",")
|
||||
.Append($"SyncMarkRecord={SyncMarkRecord}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// All parameters needed for radio setup
|
||||
/// </summary>
|
||||
public class RadioConfigurationParams
|
||||
{
|
||||
/// <summary>
|
||||
/// Pcb identification
|
||||
/// </summary>
|
||||
public String PcbId;
|
||||
/// <summary>
|
||||
/// Serial number
|
||||
/// </summary>
|
||||
public UInt32 SerialNumber;
|
||||
/// <summary>
|
||||
/// Radio address
|
||||
/// </summary>
|
||||
public UInt32 RadioAddress;
|
||||
/// <summary>
|
||||
/// Power level
|
||||
/// </summary>
|
||||
public UInt32 PowerLevel;
|
||||
/// <summary>
|
||||
/// Power level option
|
||||
/// </summary>
|
||||
public UInt32 PowerLevelOption;
|
||||
/// <summary>
|
||||
/// New code for impedance
|
||||
/// </summary>
|
||||
public UInt32 ImpedanceCodeNew;
|
||||
/// <summary>
|
||||
/// Impedance code option
|
||||
/// </summary>
|
||||
public UInt32 ImpedanceCodeOption;
|
||||
/// <summary>
|
||||
/// Encryption key
|
||||
/// </summary>
|
||||
public Byte[] EncryptionKey;
|
||||
|
||||
/// <summary>
|
||||
/// Frequency offset
|
||||
/// </summary>
|
||||
public Int16? FrqOffset { get; set; }
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RegisterToDb
|
||||
{
|
||||
/// <summary>
|
||||
/// Register address and value to DB
|
||||
/// </summary>
|
||||
/// <param name="adresse"></param>
|
||||
/// <param name="value"></param>
|
||||
public RegisterToDb(Byte[] adresse, Byte[] value)
|
||||
{
|
||||
Adresse = adresse;
|
||||
Value = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Address
|
||||
/// </summary>
|
||||
public Byte[] Adresse;
|
||||
/// <summary>
|
||||
/// Value
|
||||
/// </summary>
|
||||
public Byte[] Value;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.DataPackages
|
||||
{
|
||||
/// <summary>
|
||||
/// Temperature Time Of Flight calculation
|
||||
/// </summary>
|
||||
public struct TempTofCalc
|
||||
{
|
||||
private DateTime _refDate;
|
||||
private Double _refTemp;
|
||||
private Double _tof;
|
||||
|
||||
/// <summary>
|
||||
/// Reference data
|
||||
/// </summary>
|
||||
public DateTime RefDate { get => _refDate; set => _refDate = value; }
|
||||
/// <summary>
|
||||
/// Reference temperature
|
||||
/// </summary>
|
||||
public Double RefTemp { get => _refTemp; set => _refTemp = value; }
|
||||
/// <summary>
|
||||
/// Time Of Flight
|
||||
/// </summary>
|
||||
public Double Tof { get => _tof; set => _tof = value; }
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Setup of communication timeouts and retries for request and streaming protocol,
|
||||
/// this timeout starts the retry.
|
||||
///
|
||||
/// The individual timings of the hardware will be covert by the
|
||||
/// <see cref="TransmitPortSettings.ResponseTimeoutMs"/>
|
||||
/// injected by the different transmit protocols:
|
||||
/// <see cref="IrdaTransmitProtocol"/>
|
||||
/// <see cref="LedTransmitProtocol"/>
|
||||
/// <see cref="RfidTransmitProtocol"/>
|
||||
/// <see cref="UartTransmitProtocol"/>
|
||||
/// </summary>
|
||||
public static class CommunicationConfig
|
||||
{
|
||||
private static Int32 _requestRetries = DefaultRequestRetries;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum retries for one command at request protocol
|
||||
/// at missing response.
|
||||
/// </summary>
|
||||
public static Int32 RequestRetries
|
||||
{
|
||||
get => _requestRetries;
|
||||
set => _requestRetries = value > MaxRequestRetries ? MaxRequestRetries : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Acceptable error code as valid answer to skip retries,
|
||||
/// this might be 0x0004 for not installed application.
|
||||
/// </summary>
|
||||
public const UInt16 SkipRetryErrorCode = 0x0004;
|
||||
|
||||
/// <summary>
|
||||
/// Default retries for one command at request protocol
|
||||
/// at missing response.
|
||||
/// </summary>
|
||||
public const Int32 DefaultRequestRetries = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Limit retries to this value.
|
||||
/// </summary>
|
||||
public const Int32 MaxRequestRetries = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Send delay between records in milliseconds before
|
||||
/// new record is going to be sent or between retries,
|
||||
/// this time is independent of the timeout, it is
|
||||
/// used to delay the next send record after successful
|
||||
/// response from meter.
|
||||
/// </summary>
|
||||
public const Int32 InterRecordSendDelayMs = 5;
|
||||
//public const Int32 InterRecordSendDelayMs = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout before retry will be initiated in milliseconds
|
||||
/// for the response of the request protocol. This is an
|
||||
/// offset value, the transmission specific timing will be
|
||||
/// added from the transmit protocol timeout. This timeout
|
||||
/// will be multiplied with the (retry + 1)!
|
||||
/// </summary>
|
||||
public const Int32 ResponseTimeoutMs = 250;
|
||||
// public const Int32 ResponseTimeoutMs = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout before retry will be initiated if the meter is
|
||||
/// not ready indicated by a wakeup-message or decoding error.
|
||||
/// </summary>
|
||||
public const Int32 BusyTimeoutMs = 500;
|
||||
// public const Int32 BusyTimeoutMs = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Time to avoid automatic lock off of genesis device due to
|
||||
/// missing communication with request protocol in seconds
|
||||
/// </summary>
|
||||
public const Int32 KeepSessionTimeS = 60 * 3;
|
||||
|
||||
/// <summary>
|
||||
/// Time to update intermediate record for overflow detection
|
||||
/// during a measurement and update of short-term measurement
|
||||
/// in seconds
|
||||
/// </summary>
|
||||
public const Int32 MeasurementUpdateTimeS = 10;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig.Const
|
||||
{
|
||||
public static class MeterConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Calibration Factor on init from meter
|
||||
/// Is also the factor to convert CalibrationFactors to readable number,
|
||||
/// this is the default if the ProccessConfig.json file cannot be read.
|
||||
/// </summary>
|
||||
public const UInt16 CalibrationDefault = 15625;
|
||||
|
||||
/// <summary>
|
||||
/// Channels for calibration
|
||||
/// </summary>
|
||||
public const Int32 CalibChannels = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum calibration value in percent
|
||||
/// </summary>
|
||||
public const Double DefaultMaxCalibFactorTolerancePercent = 100.0;
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration of meter
|
||||
/// </summary>
|
||||
public class MeterConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public MeterConfig()
|
||||
{
|
||||
UseRegisterWatchService = false;
|
||||
UseErrorLogger = false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeterConfig(String file)
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(Xylem.Common.Hardware.WaterMeter.Genesis), file);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
configFile = Path.Combine(file);
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
UseRegisterWatchService = false;
|
||||
UseErrorLogger = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
using (var tr = new StreamReader(configFile))
|
||||
{
|
||||
var meterConfig = JsonConvert.DeserializeObject<MeterConfig>(tr.ReadToEnd());
|
||||
UseRegisterWatchService = meterConfig.UseRegisterWatchService;
|
||||
RegisterWatchServiceUrl = meterConfig.RegisterWatchServiceUrl;
|
||||
UseMinMaxCheck = meterConfig.UseMinMaxCheck;
|
||||
UseErrorLogger = meterConfig.UseErrorLogger;
|
||||
ErrorLoggerServiceUrl = meterConfig.ErrorLoggerServiceUrl;
|
||||
UseCalibrationLogger = meterConfig.UseCalibrationLogger;
|
||||
CalibrationLoggerServiceUrl = meterConfig.CalibrationLoggerServiceUrl;
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseRegisterWatchService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String RegisterWatchServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseMinMaxCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseErrorLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String ErrorLoggerServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseCalibrationLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String CalibrationLoggerServiceUrl { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration of meter
|
||||
/// </summary>
|
||||
public class ProccessConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public ProccessConfig()
|
||||
{
|
||||
UseRegisterWatchService = false;
|
||||
UseErrorLogger = false;
|
||||
AutoUpdateFiles = false;
|
||||
ProductionMode = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ProccessConfig(String file)
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(Xylem.Common.Hardware.WaterMeter.Genesis), file);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
configFile = Path.Combine(file);
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
UseRegisterWatchService = false;
|
||||
UseErrorLogger = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
using (var tr = new StreamReader(configFile))
|
||||
{
|
||||
var meterConfig = JsonConvert.DeserializeObject<ProccessConfig>(tr.ReadToEnd());
|
||||
UseRegisterWatchService = meterConfig.UseRegisterWatchService;
|
||||
RegisterWatchServiceUrl = meterConfig.RegisterWatchServiceUrl;
|
||||
UseMinMaxCheck = meterConfig.UseMinMaxCheck;
|
||||
UseErrorLogger = meterConfig.UseErrorLogger;
|
||||
ErrorLoggerServiceUrl = meterConfig.ErrorLoggerServiceUrl;
|
||||
UseCalibrationLogger = meterConfig.UseCalibrationLogger;
|
||||
CalibrationLoggerServiceUrl = meterConfig.CalibrationLoggerServiceUrl;
|
||||
AutoUpdateFiles = meterConfig.AutoUpdateFiles;
|
||||
ProductionMode = meterConfig.ProductionMode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Update(String file)
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(Xylem.Common.Hardware.WaterMeter.Genesis), file);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
configFile = Path.Combine(file);
|
||||
}
|
||||
|
||||
File.WriteAllText(file, JsonConvert.SerializeObject(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseRegisterWatchService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String RegisterWatchServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseMinMaxCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseErrorLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String ErrorLoggerServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseCalibrationLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String CalibrationLoggerServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool AutoUpdateFiles { get; set; }
|
||||
|
||||
[DefaultValue(true)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
|
||||
public bool ProductionMode { get; set; } = true;
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration of meter
|
||||
/// </summary>
|
||||
public class ProcessConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Load configuration file from AppRoaming or working directory
|
||||
/// </summary>
|
||||
public Boolean ReadProcessConfig()
|
||||
{
|
||||
// Check for AppRoaming
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.MeterConfigFileName);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
// Take actual working directory
|
||||
configFile = Path.Combine(ProgramConfig.MeterConfigFileName);
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
UseRegisterWatchService = false;
|
||||
UseErrorLogger = false;
|
||||
AutoUpdateFiles = false;
|
||||
ProductionMode = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
using (var tr = new StreamReader(configFile))
|
||||
{
|
||||
var meterConfig = JsonConvert.DeserializeObject<ProcessConfig>(tr.ReadToEnd());
|
||||
UseRegisterWatchService = meterConfig.UseRegisterWatchService;
|
||||
RegisterWatchServiceUrl = meterConfig.RegisterWatchServiceUrl;
|
||||
UseMinMaxCheck = meterConfig.UseMinMaxCheck;
|
||||
UseErrorLogger = meterConfig.UseErrorLogger;
|
||||
ErrorLoggerServiceUrl = meterConfig.ErrorLoggerServiceUrl;
|
||||
UseCalibrationLogger = meterConfig.UseCalibrationLogger;
|
||||
CalibrationLoggerServiceUrl = meterConfig.CalibrationLoggerServiceUrl;
|
||||
AutoUpdateFiles = meterConfig.AutoUpdateFiles;
|
||||
ProductionMode = meterConfig.ProductionMode;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write file to AppRoaming and backup it to actual working directory
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.MeterConfigFileName);
|
||||
|
||||
File.WriteAllText(configFile, JsonConvert.SerializeObject(this));
|
||||
File.WriteAllText(ProgramConfig.MeterConfigFileName, JsonConvert.SerializeObject(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseRegisterWatchService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String RegisterWatchServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseMinMaxCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseErrorLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String ErrorLoggerServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean UseCalibrationLogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public String CalibrationLoggerServiceUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Boolean AutoUpdateFiles { get; set; }
|
||||
|
||||
[DefaultValue(true)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
|
||||
public Boolean ProductionMode { get; set; }
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration of SIRT
|
||||
/// </summary>
|
||||
public class SirtConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Load SIRT configuration file from AppRoaming or working directory
|
||||
/// </summary>
|
||||
public Boolean ReadSirtConfig()
|
||||
{
|
||||
// Check for AppRoaming
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.SirtConfigFileName);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
// Take actual working directory
|
||||
configFile = Path.Combine(ProgramConfig.SirtConfigFileName);
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
SirtComport433MHz = null;
|
||||
SirtComport868MHz = null;
|
||||
ServiceSirtComport868MHz = null;
|
||||
ServiceSirtComport433MHz = null;
|
||||
SirtBoxNo = null;
|
||||
StationId = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
using (var tr = new StreamReader(configFile))
|
||||
{
|
||||
var sirtConfig = JsonConvert.DeserializeObject<SirtConfig>(tr.ReadToEnd());
|
||||
SirtComport433MHz = sirtConfig.SirtComport433MHz;
|
||||
SirtComport868MHz = sirtConfig.SirtComport868MHz;
|
||||
ServiceSirtComport433MHz = sirtConfig.ServiceSirtComport433MHz; ;
|
||||
ServiceSirtComport868MHz = sirtConfig.ServiceSirtComport868MHz; ;
|
||||
SirtBoxNo = sirtConfig.SirtBoxNo;
|
||||
StationId = sirtConfig.StationId;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write file to AppRoaming and backup it to actual working directory
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.SirtConfigFileName);
|
||||
|
||||
File.WriteAllText(configFile, JsonConvert.SerializeObject(this));
|
||||
File.WriteAllText(ProgramConfig.SirtConfigFileName, JsonConvert.SerializeObject(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comport for SIRT interface with 433MHz radio frequency
|
||||
/// </summary>
|
||||
public String SirtComport433MHz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Comport for SIRT interface with 868MHz radio frequency
|
||||
/// </summary>
|
||||
public String SirtComport868MHz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Box number for calibration settings
|
||||
/// </summary>
|
||||
public Int32? SirtBoxNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Station ID where the SIRT is used
|
||||
/// </summary>
|
||||
public Int32? StationId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Service Comport for SIRT interface with 433MHz radio frequency
|
||||
/// </summary>
|
||||
public String ServiceSirtComport433MHz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Service Comport for SIRT interface with 868MHz radio frequency
|
||||
/// </summary>
|
||||
public String ServiceSirtComport868MHz { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.Const;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Calibration content
|
||||
/// </summary>
|
||||
public class CalibFactor
|
||||
{
|
||||
/// <summary>
|
||||
/// has been calibrated
|
||||
/// </summary>
|
||||
public Boolean IsCalculated;
|
||||
|
||||
/// <summary>
|
||||
/// Channel for calibration
|
||||
/// </summary>
|
||||
public Int32 Channel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Register to store the calibration
|
||||
/// </summary>
|
||||
public String RegisterToStoreCalibFactor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ctor for calibration factor
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="registerToStoreCalibFactor"></param>
|
||||
public CalibFactor(Int32 channel, String registerToStoreCalibFactor)
|
||||
{
|
||||
Channel = channel;
|
||||
RegisterToStoreCalibFactor = registerToStoreCalibFactor;
|
||||
IsCalculated = false;
|
||||
}
|
||||
|
||||
private UInt16 _meterRawCalibFactor = MeterConfig.CalibrationDefault;
|
||||
|
||||
/// <summary>
|
||||
/// set the user readable relative (around 1.0) calibration factor
|
||||
/// and convert it to the raw calibration factor for the meter
|
||||
/// </summary>
|
||||
/// <param name="relativeCalibFactor"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void BuildMeterCalibFactor(Double relativeCalibFactor)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var tmp = Math.Round(relativeCalibFactor * GetMeterRawCalibFactor(), 0);
|
||||
|
||||
_meterRawCalibFactor = Convert.ToUInt16(tmp);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to set calibration factor", ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Read the relative (around 1.0) calibration factor calculated from the actual
|
||||
/// meter calibration factor divided by the default calibration factor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Double GetRelativeCalibFactor()
|
||||
{
|
||||
Double calibFactor = GetMeterRawCalibFactor();
|
||||
var calibDivider = GetMeterRawCalibFactorDefault();
|
||||
if (0 != calibDivider)
|
||||
{
|
||||
calibFactor /= calibDivider;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException("Default calibration factor row value is 0");
|
||||
}
|
||||
return calibFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Genesis internal raw default value (around 15625)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UInt16 GetMeterRawCalibFactorDefault()
|
||||
{
|
||||
return MeterConfig.CalibrationDefault;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the meter raw calibration factor (around 15625)
|
||||
/// </summary>
|
||||
/// <param name="meterRawCalibFactor"></param>
|
||||
public void SetMeterRawCalibFactor(UInt16 meterRawCalibFactor)
|
||||
{
|
||||
_meterRawCalibFactor = meterRawCalibFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the meter raw calibration factor (around 15625)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UInt16 GetMeterRawCalibFactor()
|
||||
{
|
||||
return _meterRawCalibFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Alarm messages
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum Alarm
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
#pragma warning disable CS1591
|
||||
REBOOT = 1 << 0, //Bit 0
|
||||
LOW_BATTERY = 1 << 1, //Bit 1
|
||||
//Bit 2
|
||||
//Bit 3
|
||||
|
||||
EMPTY_PIPE = 1 << 4, //Bit 4
|
||||
//Bit 5
|
||||
REVERSE_FLOW = 1 << 6, //Bit 6
|
||||
SUSPECT_LEAK = 1 << 7, //Bit 7
|
||||
|
||||
BROKEN_PIPE = 1 << 8, //Bit 8
|
||||
LOW_PRESSURE = 1 << 9, //Bit 9
|
||||
HIGH_PRESSURE = 1 << 10, //Bit 10
|
||||
LOW_TEMPERATURE = 1 << 11, //Bit 11
|
||||
|
||||
HIGH_TEMPERATURE = 1 << 12, //Bit 12
|
||||
RADIO_ERROR = 1 << 13, //Bit 13
|
||||
METROLOGY_PARAMS = 1 << 14, //Bit 14
|
||||
METROLOGY_MEASURE = 1 << 15, //Bit 15
|
||||
|
||||
ALL = 0x7FFFFFFF //enum is defined as Int32
|
||||
#pragma warning restore CS1591
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
class Applications
|
||||
{
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Common definition for Meter handling in production and on test benches
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// represents any error state a meter can have
|
||||
/// if hash code is 0 everything is running
|
||||
/// is Flags, so watch out to check with hasFlag!
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ErrorState
|
||||
{
|
||||
/// <summary>
|
||||
/// everything is good
|
||||
/// </summary>
|
||||
None = 0x0000,
|
||||
|
||||
/// <summary>
|
||||
/// problems on initialization
|
||||
/// </summary>
|
||||
InitFailed = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// problems on Measurement
|
||||
/// </summary>
|
||||
MeasurementFailed = 0x0002,
|
||||
|
||||
/// <summary>
|
||||
/// Problem on communication with meter
|
||||
/// </summary>
|
||||
ComErrorRequestPort = 0x0004,
|
||||
|
||||
/// <summary>
|
||||
/// Problem on optical output on meter
|
||||
/// </summary>
|
||||
ComErrorLed = 0x0008,
|
||||
|
||||
/// <summary>
|
||||
/// if pulse can not readout
|
||||
/// </summary>
|
||||
ComErrorPulse = 0x0010,
|
||||
|
||||
/// <summary>
|
||||
/// no (or no good) reference flow available
|
||||
/// </summary>
|
||||
ErrorQRef = 0x0020,
|
||||
|
||||
/// <summary>
|
||||
/// Calibration went wrong
|
||||
/// </summary>
|
||||
CalibrationFailed = 0x0040,
|
||||
|
||||
/// <summary>
|
||||
/// calibration is out of range. Check documentation from meter to find limitation
|
||||
/// </summary>
|
||||
CalibrationOutOfRange = 0x0080,
|
||||
|
||||
/// <summary>
|
||||
/// blue screen like error
|
||||
/// </summary>
|
||||
FatalError = 0x0100
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Streaming modes that supported by genesis meter.
|
||||
/// Set meter to this Streaming mode means that , the meter pushes mode-specific record to port without any responses
|
||||
/// </summary>
|
||||
public enum LedMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Test mode with raw record to log.
|
||||
/// Should give one <see cref="FlowTestRecord"/>
|
||||
/// 3 times <see cref="CalibrationRecord"/> and
|
||||
/// one <see cref="BendDetectionRecord"/>
|
||||
/// </summary>
|
||||
FlowTestAndCalibDataAndBendCorrect = 7,
|
||||
/// <summary>
|
||||
/// Test mode with raw record to log. Should give one <see cref="FlowTestRecord"/>
|
||||
/// 3 times <see cref="CalibrationRecord"/> and repeat this till led mode is switch
|
||||
/// </summary>
|
||||
FlowTestAndCalibData = 6,
|
||||
/// <summary>
|
||||
/// Test mode should give <see cref="FlowTestRecord"/> out
|
||||
/// </summary>
|
||||
FlowTestData = 4,
|
||||
/// <summary>
|
||||
/// Calibration mode should give <see cref="CalibrationRecord"/> out
|
||||
/// </summary>
|
||||
CalibData = 3,
|
||||
/// <summary>
|
||||
/// Deactivate streaming
|
||||
/// </summary>
|
||||
Off = 0,
|
||||
/// <summary>
|
||||
/// not set or an new not supported Streaming mode
|
||||
/// </summary>
|
||||
Unknown = -1
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Update capability check for all necessary settings according to meter.
|
||||
/// </summary>
|
||||
public static class MetrologyDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// It is allowed to upgrade the metrology, causing an upgrade capability check to pass always.
|
||||
/// </summary>
|
||||
public const Byte MetrologyUpgradePermitted = 0xFF;
|
||||
/// <summary>
|
||||
/// The name of the metrology application.
|
||||
/// </summary>
|
||||
public const String MetrologyName = "GENESISFLOW";
|
||||
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Power correction constants
|
||||
/// </summary>
|
||||
public static class PowCorrConst
|
||||
{
|
||||
/// <summary>
|
||||
/// Threshold for power correction EMEA version
|
||||
/// </summary>
|
||||
public const UInt32 EmeaFwThresholdForPowCorr = 0x1300;
|
||||
/// <summary>
|
||||
/// Threshold for power correction NA version
|
||||
/// </summary>
|
||||
public const UInt32 NaFNaFwThresholdForPowCorr = 0x2006;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum region radio current NA
|
||||
/// </summary>
|
||||
public const Double MinNaCurrent_uA = 119;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum region radio current sensus radio RF mode EMEA
|
||||
/// </summary>
|
||||
public const Double MinEmeaRadioRfModeCurrent_uA = 136;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum region radio current sensus radio TFX mode EMEA
|
||||
/// </summary>
|
||||
public const Double MinEmeaRadioTfxModeCurrent_uA = 155;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed current in production if production values are not logged in DB
|
||||
/// and dispatched as 0 or null.
|
||||
/// </summary>
|
||||
public const Double FixProductionCurrent_uA = 160;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed region radio current NA
|
||||
/// </summary>
|
||||
public const Double FixNaCurrent_uA = 132;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed region radio current sensus radio RF mode EMEA
|
||||
/// </summary>
|
||||
public const Double PulseReportLengthEstimate_uA = 45.453;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed region radio current sensus radio RF mode EMEA
|
||||
/// </summary>
|
||||
public const Double FixEmeaRadioRfModeCurrent_uA = 153;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed region radio current sensus radio TFX mode EMEA
|
||||
/// </summary>
|
||||
public const Double FixEmeaRadioTfxModeCurrent_uA = 174;
|
||||
|
||||
/// <summary>
|
||||
/// Pulse report length for pulse mode 1 to 4 even distribution 0
|
||||
/// </summary>
|
||||
public const UInt32 PulseReportLengthMode1To4Even0 = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Pulse report length for pulse mode 1 to 4 even distribution 1
|
||||
/// </summary>
|
||||
public const UInt32 PulseReportLengthMode1To4Even1 = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Pulse report length for pulse mode 5 to 6 even distribution 0
|
||||
/// </summary>
|
||||
public const UInt32 PulseReportLengthMode5To6Even0 = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Pulse report length for pulse mode 5 to 6 even distribution 1
|
||||
/// </summary>
|
||||
public const UInt32 PulseReportLengthMode5To6Even1 = 8;
|
||||
|
||||
/// <summary>
|
||||
/// TFX mode mask of sensus radio system state
|
||||
/// </summary>
|
||||
public const Byte SensusRadioSystemStateTfXModeMask = 0x20;
|
||||
|
||||
}
|
||||
}
|
||||
+359
@@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers.DataTypes;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers.Json;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
|
||||
using IRegister = TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.WaterMeterCore.WaterMeterRegisters.IRegister;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON filer reader for generation of register lists
|
||||
/// </summary>
|
||||
public class GenesisConfigurationReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers defined in configuration.json file
|
||||
/// </summary>
|
||||
public List<IRegister> ConfigRegistersDefinitions { get; }
|
||||
= new List<IRegister>();
|
||||
|
||||
/// <summary>
|
||||
/// Applications defined in configuration.json file
|
||||
/// </summary>
|
||||
public List<ApplicationDefinition> ConfigApplicationDefinitions { get; }
|
||||
= new List<ApplicationDefinition>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Information collected during 'configuration.json' read
|
||||
/// </summary>
|
||||
public readonly InterfaceInfo InterfaceInfo = new InterfaceInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
public GenesisConfigurationReader() { }
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
/// <param name="configFilePath">the file path for configuration.json as interface description to the meter</param>
|
||||
public GenesisConfigurationReader(String configFilePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(configFilePath))
|
||||
{
|
||||
throw new ApplicationException("JsonFileRegisterReader needs at least one file path");
|
||||
}
|
||||
if (!File.Exists(configFilePath))
|
||||
{
|
||||
throw new ApplicationException($" {configFilePath} doesn't exists");
|
||||
}
|
||||
|
||||
BuildRegisterList(File.ReadAllText(configFilePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert file content to register list
|
||||
/// </summary>
|
||||
/// <param name="configurationJson"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
/// <remarks date="??" author="Stoyan Slatev">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Aug-05" author="Thomas Wiedebusch">
|
||||
/// - AppId from Byte to UInt16 including typecast for Byte[] return. To external, it will be used as Byte
|
||||
/// as before this change. But being able to parse the configuration.json with OPTICALINTERFACE using the
|
||||
/// AppId 256, which exceeds the byte range as this isn't a real application, but will be used to identify
|
||||
/// the interface (configuration.json) version.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Aug-07" author="Thomas Wiedebusch">
|
||||
/// - Extract the max supported versions for EMEA and NA to check the supported FW.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Sep-30" author="Thomas Wiedebusch">
|
||||
/// - Supported application list introduced.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Oct-10" author="Thomas Wiedebusch">
|
||||
/// - Data size introduced including the new 'ByteArray' type and size to get rid of new defined 'uintxx_t'
|
||||
/// data types.
|
||||
/// </remarks>
|
||||
public void BuildRegisterList(String configurationJson)
|
||||
{
|
||||
IDictionary<String, AppSection> sections;
|
||||
|
||||
try
|
||||
{
|
||||
sections = JsonConvert
|
||||
.DeserializeObject<IDictionary<String, AppSection>>(configurationJson, SerializerSettings)
|
||||
?? new Dictionary<String, AppSection>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
sections = new Dictionary<String, AppSection>();
|
||||
}
|
||||
|
||||
foreach (var sectionKVP in sections)
|
||||
{
|
||||
var appId = sectionKVP.Value.Id;
|
||||
var appName = sectionKVP.Key;
|
||||
var appVersion = sectionKVP.Value.Version.Last;
|
||||
if (appName.Equals("OPTICALINTERFACE"))
|
||||
{
|
||||
var builds = sectionKVP.Value.Builds;
|
||||
var emeaBuilds = builds["emea"];
|
||||
var naBuilds = builds["na"];
|
||||
InterfaceInfo.SupportedFwVersions = new List<String>();
|
||||
foreach (var build in emeaBuilds)
|
||||
{
|
||||
InterfaceInfo.SupportedFwVersions.Add(build.FW);
|
||||
}
|
||||
foreach (var build in naBuilds)
|
||||
{
|
||||
InterfaceInfo.SupportedFwVersions.Add(build.FW);
|
||||
}
|
||||
InterfaceInfo.InterfaceVersion = TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter.BuildFwVersionStringFromDec(appVersion);
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigApplicationDefinitions.Add(new ApplicationDefinition
|
||||
{
|
||||
AppId = appId,
|
||||
AppName = appName,
|
||||
AppVersion = appVersion,
|
||||
});
|
||||
|
||||
var section = sectionKVP.Value;
|
||||
|
||||
var registers = section.Registers;
|
||||
|
||||
if (registers is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var registerKVP in registers)
|
||||
{
|
||||
var register = registerKVP.Value;
|
||||
|
||||
if (register is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var details = register.Details;
|
||||
|
||||
if (details is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var regId = register.Id;
|
||||
|
||||
foreach (var detail in details)
|
||||
{
|
||||
var values = detail.Values;
|
||||
|
||||
ConfigRegistersDefinitions.Add(new RegisterDefinition
|
||||
{
|
||||
AppAddress = appId,
|
||||
AppName = appName,
|
||||
DataType = GetType(detail.Type),
|
||||
DataSize = GetSize(detail.Type),
|
||||
Default = values?.Default is Int64 d ? d : default(Int64?),
|
||||
IsAvailable = false,
|
||||
Maximum = values?.Maximum is Int64 max ? max : default(Int64?),
|
||||
Minimum = values?.Minimum is Int64 min ? min : default(Int64?),
|
||||
RegAddressInApp = regId,
|
||||
// RegisterAddress = new byte[] { appId, regId },
|
||||
RegisterDetail = detail,
|
||||
RegisterName = registerKVP.Key,
|
||||
RestoreCapability = new StaticType(detail.StaticType)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Settings
|
||||
/// </summary>
|
||||
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||
DateParseHandling = DateParseHandling.None,
|
||||
Converters =
|
||||
{
|
||||
AccessConverter.Singleton,
|
||||
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Convert data types from interface 'configuration.json' to CLR type or array
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>type</returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
/// <remarks date="??" author="Stoyan Slatev">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Oct-10" author="Thomas Wiedebusch">
|
||||
/// - Parsed all 'uintxx_t' which are not based on CLR types to byte-array
|
||||
/// </remarks>
|
||||
private static Type GetType(String value)
|
||||
{
|
||||
// Catch all uintxx_t to split to standard CLR or to array
|
||||
var lowStrValue = value.ToLower();
|
||||
if (lowStrValue.Contains("uint") && lowStrValue.Contains("_t"))
|
||||
{
|
||||
switch (lowStrValue)
|
||||
{
|
||||
case "uint8_t": return typeof(Byte);
|
||||
case "uint16_t": return typeof(UInt16);
|
||||
case "uint32_t": return typeof(UInt32);
|
||||
case "uint64_t": return typeof(UInt64);
|
||||
default:
|
||||
return typeof(ByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
// Catch the signed standard CLR and some special types
|
||||
switch (lowStrValue)
|
||||
{
|
||||
// CLR types
|
||||
case "bool_t": return typeof(Boolean);
|
||||
case "int8_t": return typeof(SByte);
|
||||
case "int16_t": return typeof(Int16);
|
||||
case "int32_t": return typeof(Int32);
|
||||
case "int64_t": return typeof(Int64);
|
||||
case "string": return typeof(String);
|
||||
|
||||
// Special types defined in FW interface file 'configuration.json'
|
||||
case "rpc": return typeof(Rpc);
|
||||
case "time_t": return typeof(TimeT);
|
||||
case "status_t": return typeof(StatusT);
|
||||
case "enum8": return typeof(Enum8);
|
||||
default:
|
||||
throw new Exception($"Data type {value} in unknown!");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Build the data size
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>size</returns>
|
||||
/// <remarks date="2025-Oct-10" author="Thomas Wiedebusch">
|
||||
/// - Initial: - parsed all 'uintxx_t' which are not based on CLR types to byte-array
|
||||
/// </remarks>
|
||||
private static Int32 GetSize(String value)
|
||||
{
|
||||
// Catch all uintxx_t to split to standard CLR or to array
|
||||
var lowStrValue = value.ToLower();
|
||||
if (lowStrValue.Contains("uint") && lowStrValue.Contains("_t"))
|
||||
{
|
||||
switch (lowStrValue)
|
||||
{
|
||||
case "uint8_t": return sizeof(Byte);
|
||||
case "uint16_t": return sizeof(UInt16);
|
||||
case "uint32_t": return sizeof(UInt32);
|
||||
case "uint64_t": return sizeof(UInt64);
|
||||
default:
|
||||
// Extract the size from the string
|
||||
var dataSizeStr = Regex.Replace(lowStrValue, "[^0-9]", string.Empty);
|
||||
if (Int32.TryParse(dataSizeStr, out var dataSize))
|
||||
return dataSize / 8;
|
||||
throw new Exception($"Data size {lowStrValue} cannot be converted!");
|
||||
}
|
||||
}
|
||||
|
||||
// Catch the signed standard CLR and some special types
|
||||
switch (lowStrValue)
|
||||
{
|
||||
// CLR types
|
||||
case "bool_t": return sizeof(Boolean);
|
||||
case "int8_t": return sizeof(SByte);
|
||||
case "int16_t": return sizeof(Int16);
|
||||
case "int32_t": return sizeof(Int32);
|
||||
case "int64_t": return sizeof(Int64);
|
||||
|
||||
// Take just some value as the string length is unknown
|
||||
case "string": return 6 * 4;
|
||||
|
||||
// Special types defined in FW interface file 'configuration.json'
|
||||
// Remote procedure call is always a 4 byte value
|
||||
case "rpc": return sizeof(UInt32);
|
||||
|
||||
// Time will be in seconds since 01. Jan 2000 00:00:00 UTC as signed Int32
|
||||
case "time_t": return sizeof(Int32);
|
||||
case "status_t": return sizeof(UInt32);
|
||||
case "enum8": return sizeof(Byte);
|
||||
default:
|
||||
throw new Exception($"Data type {value} in unknown!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AccessConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public override Boolean CanConvert(Type t) => t == typeof(Access) || t == typeof(Access?);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="existingValue"></param>
|
||||
/// <param name="serializer"></param>
|
||||
/// <returns></returns>
|
||||
public override Object ReadJson(JsonReader reader, Type t, Object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var value = serializer.Deserialize<String>(reader);
|
||||
|
||||
return Enum.TryParse(value, true, out Access access) ? access : default(Access);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
/// <param name="untypedValue"></param>
|
||||
/// <param name="serializer"></param>
|
||||
public override void WriteJson(JsonWriter writer, Object untypedValue, JsonSerializer serializer)
|
||||
{
|
||||
if (untypedValue is Access access)
|
||||
{
|
||||
writer.WriteValue(access.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Cannot marshal type Lvl");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly AccessConverter Singleton = new AccessConverter();
|
||||
}
|
||||
}
|
||||
+3034
File diff suppressed because it is too large
Load Diff
+214
@@ -0,0 +1,214 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.SerialPorts;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Protocols.StreamingProtocol;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Check the positioning of the streaming LED to validate the quality of the communication line
|
||||
/// </summary>
|
||||
public class GenesisMeterStreamingQuality : TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter
|
||||
{
|
||||
/// <summary>
|
||||
/// Backup of last quality
|
||||
/// </summary>
|
||||
public QualityResult LastQualityResult;
|
||||
|
||||
private StreamingDecoder _sd;
|
||||
/// <summary>
|
||||
/// Quality check is active
|
||||
/// </summary>
|
||||
public Boolean IsRunning;
|
||||
private DateTimeOffset? _startTime;
|
||||
private DateTimeOffset? _stopTime;
|
||||
private List<String> _collectedRecords;
|
||||
|
||||
private Int32? _tillDecodedCount;
|
||||
/// <summary>
|
||||
/// Kick off the streaming quality check.
|
||||
/// </summary>
|
||||
/// <param name="tillDecodedCount"></param>
|
||||
/// <exception cref="ApplicationException"></exception>
|
||||
public void StartStreamingQualityCheck(Int32? tillDecodedCount = null)
|
||||
{
|
||||
|
||||
if (IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_tillDecodedCount = tillDecodedCount;
|
||||
if (_tillDecodedCount.HasValue)
|
||||
{
|
||||
_sd = new StreamingDecoder(false);
|
||||
}
|
||||
if (StreamingPort == null || !(StreamingPort is LedSerialPort))
|
||||
{
|
||||
throw new ApplicationException("No valid streaming port");
|
||||
}
|
||||
|
||||
_stopTime = null;
|
||||
_collectedRecords = new List<String>();
|
||||
|
||||
SyncStreamingBuffer(SyncMarkRecord.DecodeEveryPackage);
|
||||
((LedSerialPort)StreamingPort).OnRawRecordReceived += GenesisMeterStreamingQuality_OnRawRecordReceived;
|
||||
_startTime = DateTimeOffset.UtcNow;
|
||||
LogRawData(true);
|
||||
IsRunning = true;
|
||||
}
|
||||
|
||||
private void GenesisMeterStreamingQuality_OnRawRecordReceived(Object sender, BasePortDataEventArgs e)
|
||||
{
|
||||
_collectedRecords.Add(e.GetData().ToString());
|
||||
if (_tillDecodedCount.HasValue)
|
||||
{
|
||||
if (_sd.DecodeMsg(e.GetData().ToString()))
|
||||
{
|
||||
_tillDecodedCount = _tillDecodedCount.Value - 1;
|
||||
if (_tillDecodedCount <= 0)
|
||||
{
|
||||
IsRunning = false;
|
||||
LastQualityResult = StopStreamingQualityCheck(10);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the streaming check.
|
||||
/// </summary>
|
||||
/// <param name="sampleRateHz"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ApplicationException"></exception>
|
||||
public QualityResult StopStreamingQualityCheck(Int32 sampleRateHz)
|
||||
{
|
||||
_stopTime = DateTimeOffset.UtcNow;
|
||||
|
||||
if (!IsRunning && !_startTime.HasValue)
|
||||
{
|
||||
return new QualityResult();
|
||||
}
|
||||
|
||||
if (StreamingPort == null || !(StreamingPort is LedSerialPort))
|
||||
{
|
||||
throw new ApplicationException("No valid streaming port");
|
||||
}
|
||||
LogRawData(false);
|
||||
((LedSerialPort)StreamingPort).OnRawRecordReceived -= GenesisMeterStreamingQuality_OnRawRecordReceived;
|
||||
SyncStreamingBuffer(SyncMarkRecord.SkipDecoding);
|
||||
IsRunning = false;
|
||||
if (_stopTime != null && _startTime != null)
|
||||
return new QualityResult(_collectedRecords, _stopTime.Value - _startTime.Value, sampleRateHz);
|
||||
return new QualityResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class QualityResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Number of records received (read line for LED message)
|
||||
/// </summary>
|
||||
public readonly Int32 TotalLinesCount;
|
||||
/// <summary>
|
||||
/// Total records decoded
|
||||
/// </summary>
|
||||
public readonly Int32 TotalDecodedCount;
|
||||
/// <summary>
|
||||
/// Total errors
|
||||
/// </summary>
|
||||
public readonly Int32 TotalTransportErrorCount;
|
||||
/// <summary>
|
||||
/// Validated without errors
|
||||
/// </summary>
|
||||
public readonly Int32 TotalValidationWithoutErrorsCount;
|
||||
/// <summary>
|
||||
/// Expected lines
|
||||
/// </summary>
|
||||
public readonly Int32 ExpectedLinesCount;
|
||||
/// <summary>
|
||||
/// Time
|
||||
/// </summary>
|
||||
public readonly TimeSpan TotalTime;
|
||||
/// <summary>
|
||||
/// Error counter
|
||||
/// </summary>
|
||||
public readonly Dictionary<UInt16, Int32> ErrorOccurredCounter;
|
||||
|
||||
/// <summary>
|
||||
/// The real result of quality check
|
||||
/// </summary>
|
||||
/// <param name="collectedRecords"></param>
|
||||
/// <param name="ts"></param>
|
||||
/// <param name="sampleRateHz"></param>
|
||||
public QualityResult(List<String> collectedRecords, TimeSpan ts, Int32 sampleRateHz)
|
||||
{
|
||||
TotalLinesCount = collectedRecords.Count;
|
||||
TotalTime = ts;
|
||||
ExpectedLinesCount = (Int32)(Math.Round(ts.TotalSeconds * sampleRateHz, 0));
|
||||
ErrorOccurredCounter = new Dictionary<UInt16, Int32>();
|
||||
foreach (var rawText in collectedRecords)
|
||||
{
|
||||
var sd = new StreamingDecoder(false);
|
||||
if (!sd.DecodeMsg(rawText))
|
||||
{
|
||||
TotalTransportErrorCount++;
|
||||
continue;
|
||||
}
|
||||
//here the decoding is valid including the CRC
|
||||
TotalDecodedCount++;
|
||||
|
||||
//the DecodeMsg has assigned either a DataCalib or DataFlowTest data set
|
||||
var calibrationRecord = sd.DataCalib;
|
||||
var flowTestRecord = sd.DataFlowTest;
|
||||
var bendDetectRecord = sd.DataBendDetectTest;
|
||||
|
||||
if (flowTestRecord != null)
|
||||
{
|
||||
TotalValidationWithoutErrorsCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bendDetectRecord != null)
|
||||
{
|
||||
TotalValidationWithoutErrorsCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (calibrationRecord != null)
|
||||
{
|
||||
if (calibrationRecord.Validation == 0)
|
||||
{
|
||||
TotalValidationWithoutErrorsCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ErrorOccurredCounter.ContainsKey(calibrationRecord.Validation))
|
||||
{
|
||||
ErrorOccurredCounter[calibrationRecord.Validation] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorOccurredCounter.Add(calibrationRecord.Validation, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The quality result as dummy zero
|
||||
/// </summary>
|
||||
public QualityResult()
|
||||
{
|
||||
TotalLinesCount = 0;
|
||||
TotalTime = TimeSpan.Zero;
|
||||
ErrorOccurredCounter = new Dictionary<UInt16, Int32>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Applications;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisConfig;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Protocols.TransmitProtocol;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using IMeter = TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.WaterMeterCore.IMeter;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface of special GenesisMeter derived from IMeter
|
||||
/// </summary>
|
||||
public interface IGenesisMeter : IMeter
|
||||
{
|
||||
#region properties
|
||||
/// <summary>
|
||||
/// Represent <see cref="Register.Configexchange.PcbSerialNumber" />
|
||||
/// proposed for login
|
||||
/// </summary>
|
||||
String PcbId
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A new meter has to be checked for the reboot counter. On retries the reboot counter
|
||||
/// may have increased on unsuccessfully after-reboot procedure. This would force failing
|
||||
/// the 'ConnectCordonel'.
|
||||
/// </summary>
|
||||
Boolean CheckRebootCtr
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface information
|
||||
/// </summary>
|
||||
InterfaceInfo InterfaceInfo
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This FW version is supported by the interface "configuration.json".
|
||||
/// </summary>
|
||||
Boolean InterfaceSupportsFwVersion
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transmit protocol access for underlie objects to change response timeout
|
||||
/// </summary>
|
||||
ITransmitProtocol TransmitProtocol { get; }
|
||||
|
||||
/// <summary>
|
||||
/// List of all present meter applications installed in meter
|
||||
/// </summary>
|
||||
List<MeterApplications> MeterAppListVersion
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Successfully logged on to meter
|
||||
/// </summary>
|
||||
Boolean IsLoggedOn
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Core revision of boot code.
|
||||
/// </summary>
|
||||
Int32? CoreRevision
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Core revision of boot code as string.
|
||||
/// </summary>
|
||||
String StrCoreRevision
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the FLEXNETVERSION version which describes the entire packet.
|
||||
/// </summary>
|
||||
String FwVersion
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the FLEXNETVERSION version which describes the entire packet.
|
||||
/// </summary>
|
||||
UInt32? InstalledFwVersion
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the Metrology Lookup Table CRC.
|
||||
/// </summary>
|
||||
String LutCrc
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the meter size.
|
||||
/// </summary>
|
||||
String MeterSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Length of the meter.
|
||||
/// </summary>
|
||||
String MeterLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pressure sensor assembled to meter.
|
||||
/// </summary>
|
||||
Boolean PressureSensorAssembled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Region (EMEA, NA or China).
|
||||
/// </summary>
|
||||
String Region
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Radio frequency in MHz (433 or 868 or null).
|
||||
/// </summary>
|
||||
Int32? RadioFrequencyMhz
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metrology upgrade permission.
|
||||
/// </summary>
|
||||
Byte MetrologyUpgradePermission
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Order number under which this meter has to be produced
|
||||
/// </summary>
|
||||
Int32 OrderNumber
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Radio address
|
||||
/// </summary>
|
||||
Int64 RadioAddress
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process configuration
|
||||
/// </summary>
|
||||
ProcessConfig Configuration
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Customer serial number for informal issues
|
||||
/// </summary>
|
||||
String CustomerSerialNumber
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlocked the property change ability for special sequences.
|
||||
/// </summary>
|
||||
Boolean UnlockEssentialProperties
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region methods
|
||||
|
||||
/// <summary>
|
||||
/// Check region and size.
|
||||
/// After reading the version, all valid registers are going to be selected.
|
||||
/// </summary>
|
||||
void CheckRegionSizeLutCrc();
|
||||
|
||||
/// <summary>
|
||||
/// Unlocked the property change ability for special sequences.
|
||||
/// </summary>
|
||||
Boolean EnablePropertyChangeAbility(Boolean unlockPropertyChange);
|
||||
|
||||
/// <summary>
|
||||
/// Set the meter size if previously unlocked.
|
||||
/// The data types are: - String like "DN50" or
|
||||
/// </summary>
|
||||
Boolean SetMeterSize<T>(T meterSize);
|
||||
|
||||
/// <summary>
|
||||
/// Set the pressure sensor if previously unlocked
|
||||
/// </summary>
|
||||
Boolean SetPressureSensorAssembled(Boolean pressureSensorAssembled);
|
||||
|
||||
/// <summary>
|
||||
/// Reset the empty pipe alarm
|
||||
/// </summary>
|
||||
void ResetAlarm(Alarm clear);
|
||||
|
||||
/// <summary>
|
||||
/// Upload app list to database
|
||||
/// </summary>
|
||||
/// <param name="progressName"></param>
|
||||
/// <param name="version"></param>
|
||||
/// <returns></returns>
|
||||
StatusReturn PushProgress(String progressName, String version);
|
||||
|
||||
/// <summary>
|
||||
/// Clear password to force new password reading
|
||||
/// </summary>
|
||||
void ClearPassword();
|
||||
|
||||
/// <summary>
|
||||
/// Executes all StoreConfiguration and StoreCalibration for each application.
|
||||
/// </summary>
|
||||
/// <returns>true if all configurations are stored</returns>
|
||||
Boolean StoreAllConfigurations();
|
||||
|
||||
/// <summary>
|
||||
/// Login with identical password as last time to avoid get password from database
|
||||
/// </summary>
|
||||
Boolean ReLogin();
|
||||
|
||||
/// <summary>
|
||||
/// Returns meter registers
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
MeterRegisters GetConfigRegistersDefinitions();
|
||||
|
||||
/// <summary>
|
||||
/// Common routine for reboot being able to override this routine which will be called in
|
||||
/// MeteResetPsu to simulate a reboot.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
StatusReturn RebootGenesis();
|
||||
|
||||
/// <summary>
|
||||
/// Write Register, optional: wait for result and validate,
|
||||
/// write register will ALWAYS log the data DON'T use for password write
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Data type of Register</typeparam>
|
||||
/// <param name="regName">Register name</param>
|
||||
/// <param name="value">Value to save as byte array in raw format</param>
|
||||
/// <param name="waitForResult">wait until result is ready</param>
|
||||
/// <param name="checkRegister">check the content of the register by read back</param>
|
||||
/// <param name="skipRetryErrorCode">skip retries on this error code return</param>
|
||||
/// <returns>true on successful operation</returns>
|
||||
Boolean WriteRegister<T>(String regName, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, UInt16 skipRetryErrorCode = CommunicationConfig.SkipRetryErrorCode);
|
||||
|
||||
/// <summary>
|
||||
/// Read Register and return byte array
|
||||
/// </summary>
|
||||
/// <param name="regName">Register name</param>
|
||||
/// <param name="expectedLength">expected length for response</param>
|
||||
/// <param name="skipRetryErrorCode">skip retries on this error code return</param>
|
||||
/// <returns>value as byte array in raw format or null</returns>
|
||||
Byte[] ReadRegister(String regName, Int32? expectedLength = null,
|
||||
UInt16 skipRetryErrorCode = CommunicationConfig.SkipRetryErrorCode);
|
||||
|
||||
/// <summary>
|
||||
/// Clear all pending alarms.
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Aug-26" author="Roland Drabesch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
void ClearAlarm();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Collection of interface information
|
||||
/// </summary>
|
||||
public class InterfaceInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The interface version
|
||||
/// </summary>
|
||||
public String InterfaceVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of supported FW versions by this interface
|
||||
/// </summary>
|
||||
public List<String> SupportedFwVersions { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.ProcessExec;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.ProcessExec.EventArguments;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using MeterBatch = TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.WaterMeterCore.MeterBatch;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Port scanner:
|
||||
/// using the Windows Device Manager listed ports,
|
||||
/// tries to open the port with an exception if it cannot be accessed (very time-consuming),
|
||||
/// tries to use the request protocol to detect a Genesis device.
|
||||
/// </summary>
|
||||
public class MeterPortScanner : IProcessState, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Genesis for test access
|
||||
/// </summary>
|
||||
private TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter _currentGenesis;
|
||||
private MeterBatch _meterBatch;
|
||||
private readonly String _portType;
|
||||
|
||||
/// <summary>
|
||||
/// Auto-detected port name
|
||||
/// </summary>
|
||||
public String AutoDetectedPortName;
|
||||
|
||||
/// <summary>
|
||||
/// Port scan result event for message dispatcher to caller
|
||||
/// </summary>
|
||||
public event EventHandler<ProcessExecEventArgs> OnProcessUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Stop the port scan
|
||||
/// </summary>
|
||||
public Boolean StopPortScan;
|
||||
|
||||
/// <summary>
|
||||
/// Number of ports
|
||||
/// </summary>
|
||||
public Int32 NumberOfPorts;
|
||||
|
||||
/// <summary>
|
||||
/// Actual Port Counter
|
||||
/// </summary>
|
||||
public Int32 ActualPortCtr;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the port scan state
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2020-Oct-21" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public String GetPortScanState()
|
||||
{
|
||||
return $@"{Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrScanPort} {ActualPortCtr}/{NumberOfPorts}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
/// <returns>true if one port has been validated</returns>
|
||||
/// <remarks date="2020-Dec-11" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <param name="portType">type of communication port to meter like IrDA</param>
|
||||
public MeterPortScanner(String portType)
|
||||
{
|
||||
_portType = portType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks date="2021-Jan-05" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2021-Mai-11" author="Thomas Wiedebusch">
|
||||
/// - Remove all meters removed as _meterBatch.Dispose will remove all meters.
|
||||
/// </remarks>
|
||||
public void Dispose()
|
||||
{
|
||||
// removal from meter batch includes a disposal of meter
|
||||
_meterBatch?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use initially the port configuration to speed up search,
|
||||
/// If configuration file contains wrong port setup than scan all serial ports listed in
|
||||
/// the windows device manager,
|
||||
/// Read available ports,
|
||||
/// Try to open port and connect to Genesis meter.
|
||||
/// </summary>
|
||||
/// <param name="slot">slot to search for</param>
|
||||
/// <param name="portConfigFilePathName">configuration of port to speed up search</param>
|
||||
/// <returns>true if port found</returns>
|
||||
/// <returns>true if one port has been validated</returns>
|
||||
/// <remarks date="2020-Oct-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2020-Dec-11" author="Thomas Wiedebusch">
|
||||
/// - Port type from Ctor,
|
||||
/// - Event message changed:
|
||||
/// - Overall message: ctr / counts - ongoing scan,
|
||||
/// - Actual message: Information to log
|
||||
/// </remarks>
|
||||
/// <remarks date="2021-Jan-05" author="Thomas Wiedebusch">
|
||||
/// - Changed exit of function,
|
||||
/// - Added configuration file handling.
|
||||
/// </remarks>
|
||||
/// <remarks date="2021-Mai-11" author="Thomas Wiedebusch">
|
||||
/// - Remove all meters removed as _meterBatch.Dispose will remove all meters.
|
||||
/// </remarks>
|
||||
public Boolean ScanAllSerialPorts(Int32 slot, String portConfigFilePathName)
|
||||
{
|
||||
var serialPort = new SerialPort();
|
||||
var serialPorts = new List<String>();
|
||||
_meterBatch = new MeterBatch();
|
||||
|
||||
serialPorts.AddRange(SerialPort.GetPortNames());
|
||||
NumberOfPorts = serialPorts.Count;
|
||||
ActualPortCtr = 0;
|
||||
|
||||
// If configuration file exists, read it and check for slot setup. This will speed up the recurrent detection
|
||||
// process as at the end the detection process the detected slot will be saved.
|
||||
var slotPortConfigs = new List<SlotConfig>();
|
||||
if (portConfigFilePathName != null && File.Exists(portConfigFilePathName))
|
||||
{
|
||||
using (var tr = new StreamReader(portConfigFilePathName))
|
||||
{
|
||||
var fileStream = tr.ReadToEnd();
|
||||
var slots = JsonConvert.DeserializeObject<SlotConfig[]>(fileStream);
|
||||
if (slots != null && slots.Length > 0)
|
||||
slotPortConfigs.AddRange(slots);
|
||||
}
|
||||
|
||||
foreach (var slotPortConfig in slotPortConfigs.Where(slotPortConfig =>
|
||||
slotPortConfig.Slot == slot && !string.IsNullOrEmpty(slotPortConfig.Request.PortName)))
|
||||
{
|
||||
// add port on bottom of port list even if it is doubled that way
|
||||
NumberOfPorts++;
|
||||
serialPorts.Add(slotPortConfig.Request.PortName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("", 0,
|
||||
$@"{NumberOfPorts} {Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrPortListDeviceManger}"));
|
||||
var serialPortDetected = false;
|
||||
StopPortScan = false;
|
||||
|
||||
// start with last port,this might be added at current connection of interface
|
||||
for (var ctr = serialPorts.Count - 1; ctr >= 0; ctr--)
|
||||
{
|
||||
if (StopPortScan) break;
|
||||
ActualPortCtr++;
|
||||
serialPort.PortName = serialPorts[ctr];
|
||||
|
||||
var overallProcessCtrPercent = 100.0 * ActualPortCtr / (NumberOfPorts > 0 ? NumberOfPorts : 1);
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(GetPortScanState(), overallProcessCtrPercent,
|
||||
$@"{serialPort.PortName}: {Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrPortAccessRequest}"));
|
||||
|
||||
// skip all ports which are already opened, this might be another customer
|
||||
if (serialPort.IsOpen) continue;
|
||||
|
||||
Interfaces.Ports.PortCore.PortConfig portConfig;
|
||||
try
|
||||
{
|
||||
// removal from meter batch includes a disposal of meter
|
||||
_meterBatch.RemoveAllMeters();
|
||||
|
||||
portConfig = new PortConfig
|
||||
{
|
||||
PortName = serialPort.PortName,
|
||||
Type = _portType
|
||||
};
|
||||
|
||||
_currentGenesis = new TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter(slot, portConfig, null);
|
||||
if (_currentGenesis == null) return false;
|
||||
|
||||
// configuration has to be set BEFORE adding meter to batch to avoid e.g. auto update files
|
||||
// from network and therefore have a long network request timeout before the task starts
|
||||
_currentGenesis.Configuration.UseRegisterWatchService = false;
|
||||
_currentGenesis.Configuration.UseMinMaxCheck = false;
|
||||
_currentGenesis.Configuration.AutoUpdateFiles = false;
|
||||
_meterBatch.AddMeter(_currentGenesis);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(GetPortScanState(), overallProcessCtrPercent,
|
||||
$@"{serialPort.PortName}: {Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrPortFailedToOpen}"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// if port cannot be opened on access to the port is senseless, try the next port
|
||||
if (_currentGenesis != null && !_currentGenesis.RequestPort.IsOpen()) continue;
|
||||
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(GetPortScanState(), overallProcessCtrPercent,
|
||||
$@"{serialPort.PortName}: {Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrPortSuccessfullyAccessed}"));
|
||||
|
||||
// read PCB ID from meter, this is the indicator, that a Genesis is connected to this port
|
||||
if (_currentGenesis == null || string.Empty == _currentGenesis.GetPcbId())
|
||||
{
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(GetPortScanState(), overallProcessCtrPercent,
|
||||
$@"{serialPort.PortName}: {Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources.StrRequestPortDetectionFailed}"));
|
||||
continue;
|
||||
}
|
||||
AutoDetectedPortName = serialPort.PortName;
|
||||
serialPortDetected = true;
|
||||
|
||||
// check if needed to store new configuration if slot and port name is not in file
|
||||
if (!slotPortConfigs.Any(c => c.Slot == slot && c.Request.PortName == AutoDetectedPortName))
|
||||
{
|
||||
slotPortConfigs.Add(new SlotConfig() { Slot = slot, Request = portConfig });
|
||||
var text = JsonConvert.SerializeObject(slotPortConfigs);
|
||||
if (portConfigFilePathName != null)
|
||||
File.WriteAllText(portConfigFilePathName, text);
|
||||
}
|
||||
|
||||
// stop loop if one Genesis has been detected
|
||||
break;
|
||||
}
|
||||
|
||||
serialPort.Dispose();
|
||||
// removal from meter batch includes a disposal of meter
|
||||
_meterBatch?.Dispose();
|
||||
|
||||
return serialPortDetected;
|
||||
}
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Power correction parameters used for overestimated power consumption on
|
||||
/// Cordonel FW update from:
|
||||
/// EMEA below R1.3.x
|
||||
/// NA below R2.0.07
|
||||
/// </summary>
|
||||
public class PowerCorrection
|
||||
{
|
||||
#region Data Base at EOL - Production
|
||||
/// <summary>
|
||||
/// Unique identification of PCB
|
||||
/// </summary>
|
||||
public String PcbId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date time UTC at EOL - Production
|
||||
/// </summary>
|
||||
public DateTime? ProductionDateTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total used seconds at EOL - Production
|
||||
/// </summary>
|
||||
public UInt32 ProductionTotalUsedSeconds_s { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total used charge of batteries at EOL - Production
|
||||
/// </summary>
|
||||
public UInt64 ProductionTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Radio system state at EOL - Production
|
||||
/// </summary>
|
||||
public Byte? ProductionRadioSystemState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse adapter was installed during at EOL - Production VAKO
|
||||
/// </summary>
|
||||
public Boolean ProductionPulseAdapterIsInstalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse mode during at EOL - Production
|
||||
/// </summary>
|
||||
public Byte ProductionPulseMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse sequence counter during at EOL - Production
|
||||
/// </summary>
|
||||
public Byte ProductionPulseSequenceCounter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse distribution at EOL - Production
|
||||
/// </summary>
|
||||
public Boolean ProductionPulseEvenDistribution { get; set; }
|
||||
|
||||
#endregion
|
||||
#region Maintenance readout
|
||||
|
||||
/// <summary>
|
||||
/// Detected FW version before maintenance
|
||||
/// </summary>
|
||||
public UInt32? ActualFwVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date time UTC at time of maintenance
|
||||
/// </summary>
|
||||
public DateTime? ActualDateTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total used seconds of entire runtime
|
||||
/// </summary>
|
||||
public UInt32 ActualTotalUsedSeconds_s { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total used charge of batteries of entire runtime
|
||||
/// </summary>
|
||||
public UInt64 ActualTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Actual detected radio system state at maintenance
|
||||
/// </summary>
|
||||
public Byte? ActualRadioSystemState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Detection of pulse adapter installation
|
||||
/// </summary>
|
||||
public Boolean ActualPulseAdapterIsInstalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse mode during maintenance
|
||||
/// </summary>
|
||||
public Byte ActualPulseMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse sequence counter during maintenance
|
||||
/// </summary>
|
||||
public Byte ActualPulseSequenceCounter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pulse distribution during maintenance
|
||||
/// </summary>
|
||||
public Boolean ActualPulseEvenDistribution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Mark pulse adapter as installed on any detected or sequence counted
|
||||
/// </summary>
|
||||
public Boolean PulseAdapterMarkedAsInstalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Remind battery quantity used for estimation of drained load
|
||||
/// </summary>
|
||||
public Int32 BatteryQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Remind battery initial load used for estimation of drained load
|
||||
/// </summary>
|
||||
public UInt32 InitialBatteryLoad_mAh { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Maintenance calculation
|
||||
|
||||
/// <summary>
|
||||
/// FW version for the update
|
||||
/// </summary>
|
||||
public UInt32? RequiredFwVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calculated pulse report length
|
||||
/// </summary>
|
||||
public UInt32 PulseReportLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total used seconds after EOL and before maintenance
|
||||
/// </summary>
|
||||
public UInt32 PostProductionTotalUsedSeconds_s { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Overestimated total used charge before maintenance
|
||||
/// </summary>
|
||||
public UInt64 OverestimatedTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Based on fixed estimation total used charge before maintenance
|
||||
/// </summary>
|
||||
public UInt64 FixedEstimateTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lowest threshold for total used charge calculated during maintenance
|
||||
/// </summary>
|
||||
public UInt64 MinimumTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Corrected total used charge during maintenance
|
||||
/// </summary>
|
||||
public UInt64? CorrectedTotalUsedCharge_uAs { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Read of required registers and calculation of power correction
|
||||
/// </summary>
|
||||
public class PowerCorrectionCalc
|
||||
{
|
||||
private readonly TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter _currentGenesis;
|
||||
private readonly PowerCorrection _powCorr;
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
/// <param name="currentGenesis"></param>
|
||||
/// <param name="powCorr"></param>
|
||||
/// <returns>true if successful</returns>
|
||||
public PowerCorrectionCalc(TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter currentGenesis, PowerCorrection powCorr)
|
||||
{
|
||||
_currentGenesis = currentGenesis;
|
||||
_powCorr = powCorr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the values for power correction
|
||||
/// </summary>
|
||||
/// <returns>true if successful</returns>
|
||||
/// <remarks date="2024-May-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public Boolean PowerCorrEstimation()
|
||||
{
|
||||
if (_currentGenesis == null || _powCorr == null)
|
||||
return false;
|
||||
|
||||
var logOnReminder = _currentGenesis.IsLoggedOn;
|
||||
var retVal = _currentGenesis.ReLogin();
|
||||
if (retVal)
|
||||
{
|
||||
_powCorr.CorrectedTotalUsedCharge_uAs = null;
|
||||
// read registers
|
||||
_powCorr.ActualPulseSequenceCounter = RegisterConverter.ByteArrayToValue<Byte>(
|
||||
_currentGenesis.ReadRegister(Register.Irda.PulseSequence));
|
||||
_powCorr.ActualPulseEvenDistribution = RegisterConverter.ByteArrayToValue<Boolean>(
|
||||
_currentGenesis.ReadRegister(Register.Metrologyasst.PulseEvenDistribution));
|
||||
_powCorr.ActualPulseMode = RegisterConverter.ByteArrayToValue<Byte>(
|
||||
_currentGenesis.ReadRegister(Register.Metrologyasst.PulseMode));
|
||||
_powCorr.ActualRadioSystemState = RegisterConverter.ByteArrayToValue<Byte>(
|
||||
_currentGenesis.ReadRegister(Register.Sensusradio.SystemState));
|
||||
_powCorr.ActualTotalUsedSeconds_s = RegisterConverter.ByteArrayToValue<UInt32>(
|
||||
_currentGenesis.ReadRegister(Register.Powermon.BatteryExceededSeconds));
|
||||
_powCorr.ActualTotalUsedCharge_uAs = RegisterConverter.ByteArrayToValue<UInt64>(
|
||||
_currentGenesis.ReadRegister(Register.Powermon.BatteryDrainedLoad, 8));
|
||||
_powCorr.BatteryQuantity = RegisterConverter.ByteArrayToValue<Int32>(
|
||||
_currentGenesis.ReadRegister(Register.Powermon.BatteryQuantity));
|
||||
_powCorr.InitialBatteryLoad_mAh = RegisterConverter.ByteArrayToValue<UInt32>(
|
||||
_currentGenesis.ReadRegister(Register.Powermon.BatteryInitialLoad));
|
||||
|
||||
if (!logOnReminder)
|
||||
_currentGenesis.Logout();
|
||||
|
||||
// get actual time from PC
|
||||
_powCorr.ActualDateTimeUtc = DateTime.UtcNow;
|
||||
|
||||
// skip if indicated that a pulse adapter never has been installed
|
||||
_powCorr.PulseAdapterMarkedAsInstalled =
|
||||
_powCorr.ProductionPulseAdapterIsInstalled ||
|
||||
_powCorr.ActualPulseAdapterIsInstalled;
|
||||
|
||||
if (!_powCorr.PulseAdapterMarkedAsInstalled)
|
||||
return true;
|
||||
|
||||
// calculate post production used seconds
|
||||
if (_powCorr.ProductionTotalUsedSeconds_s > _powCorr.ActualTotalUsedSeconds_s)
|
||||
_powCorr.PostProductionTotalUsedSeconds_s = _powCorr.ActualTotalUsedSeconds_s;
|
||||
else
|
||||
_powCorr.PostProductionTotalUsedSeconds_s = _powCorr.ActualTotalUsedSeconds_s -
|
||||
_powCorr.ProductionTotalUsedSeconds_s;
|
||||
|
||||
// preset production used charge if not received from DB as logging of this value
|
||||
// in early production processes was not granted
|
||||
if (_powCorr.ProductionTotalUsedCharge_uAs == 0)
|
||||
_powCorr.ProductionTotalUsedCharge_uAs = (UInt64)(_powCorr.ProductionTotalUsedSeconds_s *
|
||||
PowCorrConst.FixProductionCurrent_uA);
|
||||
// calculate pulse report length
|
||||
if ((_powCorr.ActualPulseMode >= 1 && _powCorr.ActualPulseMode <= 4) ||
|
||||
(_powCorr.ProductionPulseMode >= 1 && _powCorr.ProductionPulseMode <= 4))
|
||||
{
|
||||
_powCorr.PulseReportLength = PowCorrConst.PulseReportLengthMode1To4Even0;
|
||||
if (_powCorr.ActualPulseEvenDistribution)
|
||||
_powCorr.PulseReportLength = PowCorrConst.PulseReportLengthMode1To4Even1;
|
||||
}
|
||||
else if ((_powCorr.ActualPulseMode >= 5 && _powCorr.ActualPulseMode <= 6) ||
|
||||
(_powCorr.ProductionPulseMode >= 5 && _powCorr.ProductionPulseMode <= 6))
|
||||
{
|
||||
_powCorr.PulseReportLength = PowCorrConst.PulseReportLengthMode5To6Even0;
|
||||
if (_powCorr.ActualPulseEvenDistribution)
|
||||
_powCorr.PulseReportLength = PowCorrConst.PulseReportLengthMode5To6Even1;
|
||||
}
|
||||
|
||||
// calculate overestimation based on pulse report length
|
||||
_powCorr.OverestimatedTotalUsedCharge_uAs = 0;
|
||||
if ((_powCorr.ActualPulseMode >= 1 && _powCorr.ActualPulseMode <= 6) ||
|
||||
(_powCorr.ProductionPulseMode >= 1 && _powCorr.ProductionPulseMode <= 6))
|
||||
{
|
||||
_powCorr.OverestimatedTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.PulseReportLength * PowCorrConst.PulseReportLengthEstimate_uA *
|
||||
_powCorr.PostProductionTotalUsedSeconds_s);
|
||||
}
|
||||
|
||||
Byte radioSystemState = 0;
|
||||
if (_powCorr.ActualRadioSystemState != null)
|
||||
{
|
||||
radioSystemState = (Byte)_powCorr.ActualRadioSystemState;
|
||||
}
|
||||
else if (_powCorr.ProductionRadioSystemState != null)
|
||||
{
|
||||
radioSystemState = (Byte)_powCorr.ProductionRadioSystemState;
|
||||
}
|
||||
|
||||
if (_currentGenesis.Region == "NA")
|
||||
{
|
||||
_powCorr.MinimumTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.MinNaCurrent_uA);
|
||||
_powCorr.FixedEstimateTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.FixNaCurrent_uA);
|
||||
}
|
||||
else if (_currentGenesis.Region == "EMEA" &&
|
||||
(radioSystemState & PowCorrConst.SensusRadioSystemStateTfXModeMask) ==
|
||||
PowCorrConst.SensusRadioSystemStateTfXModeMask)
|
||||
{
|
||||
_powCorr.MinimumTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.MinEmeaRadioTfxModeCurrent_uA);
|
||||
_powCorr.FixedEstimateTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.FixEmeaRadioTfxModeCurrent_uA);
|
||||
}
|
||||
else if (_currentGenesis.Region == "EMEA" &&
|
||||
(radioSystemState & PowCorrConst.SensusRadioSystemStateTfXModeMask) !=
|
||||
PowCorrConst.SensusRadioSystemStateTfXModeMask)
|
||||
{
|
||||
_powCorr.MinimumTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.MinEmeaRadioRfModeCurrent_uA);
|
||||
_powCorr.FixedEstimateTotalUsedCharge_uAs =
|
||||
(UInt64)(_powCorr.ActualTotalUsedSeconds_s * PowCorrConst.FixEmeaRadioRfModeCurrent_uA);
|
||||
}
|
||||
|
||||
if (_powCorr.OverestimatedTotalUsedCharge_uAs > _powCorr.ActualTotalUsedCharge_uAs)
|
||||
_powCorr.CorrectedTotalUsedCharge_uAs = 0;
|
||||
else
|
||||
_powCorr.CorrectedTotalUsedCharge_uAs = _powCorr.ActualTotalUsedCharge_uAs -
|
||||
_powCorr.OverestimatedTotalUsedCharge_uAs;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculate the values for power correction
|
||||
/// </summary>
|
||||
/// <returns>true if successful</returns>
|
||||
/// <remarks date="2024-May-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public Boolean CorrectPowerConsumption()
|
||||
{
|
||||
if (_currentGenesis == null || _powCorr == null || _powCorr.CorrectedTotalUsedCharge_uAs == null)
|
||||
return false;
|
||||
|
||||
// check which value should be applied and set the CorrectedTotalUsedCharge_uAs
|
||||
if (_powCorr.ProductionPulseAdapterIsInstalled)
|
||||
{
|
||||
// avoid undershot below smallest value
|
||||
if (_powCorr.CorrectedTotalUsedCharge_uAs < _powCorr.MinimumTotalUsedCharge_uAs)
|
||||
_powCorr.CorrectedTotalUsedCharge_uAs = _powCorr.MinimumTotalUsedCharge_uAs;
|
||||
}
|
||||
else // retrofitted
|
||||
{
|
||||
// correct to smaller value and mark corrected = actual to log that correction not needed
|
||||
_powCorr.CorrectedTotalUsedCharge_uAs =
|
||||
_powCorr.ActualTotalUsedCharge_uAs > _powCorr.FixedEstimateTotalUsedCharge_uAs ?
|
||||
_powCorr.FixedEstimateTotalUsedCharge_uAs : _powCorr.ActualTotalUsedCharge_uAs;
|
||||
}
|
||||
|
||||
if (_powCorr.ActualTotalUsedCharge_uAs == _powCorr.CorrectedTotalUsedCharge_uAs)
|
||||
return true;
|
||||
|
||||
// save corrected power consumption data to meter
|
||||
var logOnReminder = _currentGenesis.IsLoggedOn;
|
||||
var retVal = _currentGenesis.ReLogin();
|
||||
if (retVal)
|
||||
{
|
||||
var retriesLeft = 2;
|
||||
do
|
||||
{
|
||||
// write the new calculated value
|
||||
retVal = _currentGenesis.WriteRegister(Register.Powermon.BatteryDrainedLoad,
|
||||
RegisterConverter.ValueToByteArray(_powCorr.CorrectedTotalUsedCharge_uAs));
|
||||
if (!retVal)
|
||||
continue;
|
||||
|
||||
// store configuration
|
||||
retVal = _currentGenesis.WriteRegister(Register.Powermon.StoreConfiguration, 1);
|
||||
if (!retVal)
|
||||
continue;
|
||||
|
||||
var readResult = _currentGenesis.ReadRegister(Register.Powermon.StoreConfiguration);
|
||||
retVal = readResult != null && readResult.ToList().All(array => array == 0x00);
|
||||
} while (!retVal && retriesLeft-- > 0);
|
||||
}
|
||||
|
||||
if (!logOnReminder)
|
||||
_currentGenesis.Logout();
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
public class PreadjustmentMeter : TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.GenesisMeter
|
||||
{
|
||||
private settings mySettings = new settings();
|
||||
public class settings
|
||||
{
|
||||
public int Metersize { get; set; } = 2;
|
||||
|
||||
}
|
||||
|
||||
public void Preparation()
|
||||
{
|
||||
//Login
|
||||
//getRegisterList
|
||||
Login();
|
||||
|
||||
WriteRegister(Register.Genesisflow.CalFactor1, 15625);
|
||||
WriteRegister(Register.Genesisflow.CalFactor2, 15625);
|
||||
WriteRegister(Register.Genesisflow.CalFactor3, 15625);
|
||||
WriteRegister(Register.Genesisflow.ZeroOffset1, 0);
|
||||
WriteRegister(Register.Genesisflow.ZeroOffset2, 0);
|
||||
WriteRegister(Register.Genesisflow.ZeroOffset3, 0);
|
||||
WriteRegister(Register.Genesisflow.LedMode, 6);
|
||||
WriteRegister(Register.Genesisflow.MeterSize, mySettings.Metersize);
|
||||
|
||||
|
||||
|
||||
//var r = LocalWebRequest.GetRequest($"{ ServiceUrls.GenesisFinalCheckServiceUrl()}GetMetersizeProgrammingData?MeterSize={mySettings.Metersize.GetHashCode().GetHashCode()}", 2000);
|
||||
//var dt = JsonConvert.DeserializeObject<Dictionary<string, UInt32>>(r);
|
||||
|
||||
// foreach (var item in dt)
|
||||
// {
|
||||
// WriteRegister(item.Key, item.Value);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public void RunAmp()
|
||||
{
|
||||
for (int i = 0; i < 35; i++)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Missing or invalid register definition (configuration.json)! Search in:.
|
||||
/// </summary>
|
||||
internal static string StrErrorMissingConfiguration {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMissingConfiguration", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot Open Comport. Check TaskManager for other Genesis relevant programs and close them! Also check if the comport is valid!.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgComPort {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgComPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Could not find a CSD parameter in register list!.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgCsdMissing {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgCsdMissing", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Could not find register in register list! Check configuration.json for latest version!.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgRegisterNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgRegisterNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Could not write register!.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgRegisterWrite {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgRegisterWrite", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Read back.
|
||||
/// </summary>
|
||||
internal static string StrMeterValue {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMeterValue", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Access request..
|
||||
/// </summary>
|
||||
internal static string StrPortAccessRequest {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPortAccessRequest", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to open..
|
||||
/// </summary>
|
||||
internal static string StrPortFailedToOpen {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPortFailedToOpen", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Ports listed in the Windows device manager..
|
||||
/// </summary>
|
||||
internal static string StrPortListDeviceManger {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPortListDeviceManger", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatic port scan started..
|
||||
/// </summary>
|
||||
internal static string StrPortScanStarted {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPortScanStarted", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Successfully accessed..
|
||||
/// </summary>
|
||||
internal static string StrPortSuccessfullyAccessed {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPortSuccessfullyAccessed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Read register.
|
||||
/// </summary>
|
||||
internal static string StrReadRegister {
|
||||
get {
|
||||
return ResourceManager.GetString("StrReadRegister", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reading registers after maintenance.
|
||||
/// </summary>
|
||||
internal static string StrReadRegistersAfterUpdate {
|
||||
get {
|
||||
return ResourceManager.GetString("StrReadRegistersAfterUpdate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reading registers before maintenance.
|
||||
/// </summary>
|
||||
internal static string StrReadRegistersBeforeUpdate {
|
||||
get {
|
||||
return ResourceManager.GetString("StrReadRegistersBeforeUpdate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Compare register.
|
||||
/// </summary>
|
||||
internal static string StrRegisterCompare {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterCompare", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Comparison failed!.
|
||||
/// </summary>
|
||||
internal static string StrRegisterCompareFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterCompareFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Successfully compared..
|
||||
/// </summary>
|
||||
internal static string StrRegisterCompareSucceeded {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterCompareSucceeded", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Execute configuration sequence.....
|
||||
/// </summary>
|
||||
internal static string StrRegisterRecoveryExec {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterRecoveryExec", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finalize configuration sequence.....
|
||||
/// </summary>
|
||||
internal static string StrRegisterRecoveryFinalization {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterRecoveryFinalization", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Prepare configuration sequence.....
|
||||
/// </summary>
|
||||
internal static string StrRegisterRecoveryPreparation {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterRecoveryPreparation", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Register value is out of range!.
|
||||
/// </summary>
|
||||
internal static string StrRegisterValueOutOfRange {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRegisterValueOutOfRange", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cordonel not detected!.
|
||||
/// </summary>
|
||||
internal static string StrRequestPortDetectionFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("StrRequestPortDetectionFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Scan port.
|
||||
/// </summary>
|
||||
internal static string StrScanPort {
|
||||
get {
|
||||
return ResourceManager.GetString("StrScanPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to WARNING: Register value set to default.
|
||||
/// </summary>
|
||||
internal static string StrSetRegisterToDefault {
|
||||
get {
|
||||
return ResourceManager.GetString("StrSetRegisterToDefault", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Write register.
|
||||
/// </summary>
|
||||
internal static string StrWriteRegister {
|
||||
get {
|
||||
return ResourceManager.GetString("StrWriteRegister", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="StrPortAccessRequest" xml:space="preserve">
|
||||
<value>Teste Zugriff.</value>
|
||||
</data>
|
||||
<data name="StrPortFailedToOpen" xml:space="preserve">
|
||||
<value>Zugriff verweigert.</value>
|
||||
</data>
|
||||
<data name="StrPortListDeviceManger" xml:space="preserve">
|
||||
<value>Kommunikationsanschlüsse im Windows Gerätemanager.</value>
|
||||
</data>
|
||||
<data name="StrPortScanStarted" xml:space="preserve">
|
||||
<value>Automatische Erkennung gestartet.</value>
|
||||
</data>
|
||||
<data name="StrPortSuccessfullyAccessed" xml:space="preserve">
|
||||
<value>Zugriff erfolgreich.</value>
|
||||
</data>
|
||||
<data name="StrRequestPortDetectionFailed" xml:space="preserve">
|
||||
<value>Keinen Cordonel erkannt!</value>
|
||||
</data>
|
||||
<data name="StrScanPort" xml:space="preserve">
|
||||
<value>Suche Anschluß....</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompare" xml:space="preserve">
|
||||
<value>Vergleiche Register</value>
|
||||
</data>
|
||||
<data name="StrReadRegister" xml:space="preserve">
|
||||
<value>Lese Register</value>
|
||||
</data>
|
||||
<data name="StrWriteRegister" xml:space="preserve">
|
||||
<value>Schreibe Register</value>
|
||||
</data>
|
||||
<data name="StrReadRegistersBeforeUpdate" xml:space="preserve">
|
||||
<value>Lese Register vor der Wartung</value>
|
||||
</data>
|
||||
<data name="StrReadRegistersAfterUpdate" xml:space="preserve">
|
||||
<value>Lese Register nach der Wartung</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryExec" xml:space="preserve">
|
||||
<value>Ausführung der Konfigurationsequenz....</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryFinalization" xml:space="preserve">
|
||||
<value>Abschließen der Konfigurationsequenz....</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryPreparation" xml:space="preserve">
|
||||
<value>Vorbereitung der Konfigurationsequenz....</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompareFailed" xml:space="preserve">
|
||||
<value>FEHLER: Vergleich fehlgeschlagen!</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompareSucceeded" xml:space="preserve">
|
||||
<value>Vergleich erfolgreich.</value>
|
||||
</data>
|
||||
<data name="StrMeterValue" xml:space="preserve">
|
||||
<value>Zurückgelesen</value>
|
||||
</data>
|
||||
<data name="StrSetRegisterToDefault" xml:space="preserve">
|
||||
<value>WARNUNG: Registerwert auf Standardwert gesetzt</value>
|
||||
</data>
|
||||
<data name="StrRegisterValueOutOfRange" xml:space="preserve">
|
||||
<value>FEHLER: Registerwert außerhalb des zulässigen Bereiches!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdMissing" xml:space="preserve">
|
||||
<value>FEHLER: Kein CSD Parameter in Parameterliste gefunden!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRegisterNotFound" xml:space="preserve">
|
||||
<value>FEHLER: Register nicht in Registerliste gefunden! Version der Configuration.json prüfen!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRegisterWrite" xml:space="preserve">
|
||||
<value>FEHLER: Register konnte nicht geschrieben werden!</value>
|
||||
</data>
|
||||
<data name="StrErrorMissingConfiguration" xml:space="preserve">
|
||||
<value>FEHLER: Konfigurationsdatei (configuration.json) nicht gefunden oder ungültig! Erwartetes Verzeichnis:</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgComPort" xml:space="preserve">
|
||||
<value>Kommunikationsanschluß nicht vorhanden oder von anderer Genesis App blockiert! Bitte TaskManger starten und prüfen!</value>
|
||||
</data>
|
||||
</root>
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="StrPortAccessRequest" xml:space="preserve">
|
||||
<value>Access request.</value>
|
||||
</data>
|
||||
<data name="StrPortFailedToOpen" xml:space="preserve">
|
||||
<value>Failed to open.</value>
|
||||
</data>
|
||||
<data name="StrPortListDeviceManger" xml:space="preserve">
|
||||
<value>Ports listed in the Windows device manager.</value>
|
||||
</data>
|
||||
<data name="StrPortScanStarted" xml:space="preserve">
|
||||
<value>Automatic port scan started.</value>
|
||||
</data>
|
||||
<data name="StrPortSuccessfullyAccessed" xml:space="preserve">
|
||||
<value>Successfully accessed.</value>
|
||||
</data>
|
||||
<data name="StrRequestPortDetectionFailed" xml:space="preserve">
|
||||
<value>Cordonel not detected!</value>
|
||||
</data>
|
||||
<data name="StrScanPort" xml:space="preserve">
|
||||
<value>Scan port</value>
|
||||
</data>
|
||||
<data name="StrReadRegistersAfterUpdate" xml:space="preserve">
|
||||
<value>Reading registers after maintenance</value>
|
||||
</data>
|
||||
<data name="StrReadRegistersBeforeUpdate" xml:space="preserve">
|
||||
<value>Reading registers before maintenance</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompare" xml:space="preserve">
|
||||
<value>Compare register</value>
|
||||
</data>
|
||||
<data name="StrReadRegister" xml:space="preserve">
|
||||
<value>Read register</value>
|
||||
</data>
|
||||
<data name="StrWriteRegister" xml:space="preserve">
|
||||
<value>Write register</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryExec" xml:space="preserve">
|
||||
<value>Execute configuration sequence....</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryFinalization" xml:space="preserve">
|
||||
<value>Finalize configuration sequence....</value>
|
||||
</data>
|
||||
<data name="StrRegisterRecoveryPreparation" xml:space="preserve">
|
||||
<value>Prepare configuration sequence....</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompareFailed" xml:space="preserve">
|
||||
<value>ERROR: Comparison failed!</value>
|
||||
</data>
|
||||
<data name="StrRegisterCompareSucceeded" xml:space="preserve">
|
||||
<value>Successfully compared.</value>
|
||||
</data>
|
||||
<data name="StrMeterValue" xml:space="preserve">
|
||||
<value>Read back</value>
|
||||
</data>
|
||||
<data name="StrSetRegisterToDefault" xml:space="preserve">
|
||||
<value>WARNING: Register value set to default</value>
|
||||
</data>
|
||||
<data name="StrRegisterValueOutOfRange" xml:space="preserve">
|
||||
<value>ERROR: Register value is out of range!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdMissing" xml:space="preserve">
|
||||
<value>ERROR: Could not find a CSD parameter in register list!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRegisterNotFound" xml:space="preserve">
|
||||
<value>ERROR: Could not find register in register list! Check configuration.json for latest version!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRegisterWrite" xml:space="preserve">
|
||||
<value>ERROR: Could not write register!</value>
|
||||
</data>
|
||||
<data name="StrErrorMissingConfiguration" xml:space="preserve">
|
||||
<value>ERROR: Missing or invalid register definition (configuration.json)! Search in:</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgComPort" xml:space="preserve">
|
||||
<value>Cannot Open Comport. Check TaskManager for other Genesis relevant programs and close them! Also check if the comport is valid!</value>
|
||||
</data>
|
||||
</root>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
</SettingsFile>
|
||||
+1831
File diff suppressed because it is too large
Load Diff
+237
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.Const;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
using Xylem.Common.Metrology.Measurements.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
public partial class GenesisMeter
|
||||
{
|
||||
/// <summary>
|
||||
/// Calibration factors for all channels
|
||||
/// </summary>
|
||||
private readonly CalibFactor[] _calibFactor = new CalibFactor[MeterConfig.CalibChannels];
|
||||
|
||||
/// <summary>
|
||||
/// Registers needed to store the calibration for the individual channel
|
||||
/// </summary>
|
||||
private readonly String[] _registersToStoreCalibFactor =
|
||||
{
|
||||
Register.Genesisflow.CalFactor1,
|
||||
Register.Genesisflow.CalFactor2,
|
||||
Register.Genesisflow.CalFactor3
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void InitCalibration()
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - Init calibration and set calibration values of all channels to default");
|
||||
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
|
||||
{
|
||||
_calibFactor[channel] = new CalibFactor(channel, _registersToStoreCalibFactor[channel]);
|
||||
WriteRegister(_registersToStoreCalibFactor[channel],
|
||||
_calibFactor[channel].GetMeterRawCalibFactorDefault(), checkRegister: true);
|
||||
}
|
||||
|
||||
PreMeasurement();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StartCalibration()
|
||||
{
|
||||
StartMeasurement();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Just stop recording without calculation
|
||||
/// </summary>
|
||||
public void StopCalibration()
|
||||
{
|
||||
StopMeasurement();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeasurementStates GetCalibrationState()
|
||||
{
|
||||
return GetMeasurementState();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void BuildAndCheckCalibFactorsAllChannels(Double refVolumeCm, Double? refTimeS, Double reqDeviationPercent, Double maxCalibFactorTolerancePercent = MeterConfig.DefaultMaxCalibFactorTolerancePercent, int? testrunNr = null)
|
||||
{
|
||||
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
|
||||
{
|
||||
_calibFactor[channel] = new CalibFactor(channel, _registersToStoreCalibFactor[channel]);
|
||||
}
|
||||
|
||||
foreach (var item in Enumerable.Where<IMeasurement>(_listOfIMeasurement, m => m.GetType() == typeof(CalibrationRecord)))
|
||||
{
|
||||
if (!(item is CalibrationMeasurement))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var calib = item as CalibrationMeasurement;
|
||||
var channel = calib.GetChannel();
|
||||
|
||||
if (channel == 0 || channel > MeterConfig.CalibChannels)
|
||||
{
|
||||
var message = $"Slot:{Slot}, Channel:{channel} - Calibration channel out of range";
|
||||
Logger.Warn(message);
|
||||
throw new ApplicationException(message);
|
||||
}
|
||||
|
||||
Logger.Info($"Slot:{Slot}, Channel:{channel} - Calculate Calibrationfactor Relative(RefVolumeCm:{refVolumeCm}, refTimeS:{refTimeS},reqDeviationPercent:{reqDeviationPercent})");
|
||||
|
||||
var calibFactorRel = calib.CalculateCalibFactorRel(refVolumeCm, refTimeS, reqDeviationPercent);
|
||||
|
||||
//if the null return indicates an invalid calibration factor the calibFactorX.IsCalculated remains false
|
||||
if (null == calibFactorRel)
|
||||
{
|
||||
var message = $"Slot:{Slot}, Channel:{channel} - Calibration factor not calculated";
|
||||
Logger.Warn(message);
|
||||
throw new ApplicationException(message);
|
||||
}
|
||||
|
||||
|
||||
_calibFactor[channel - 1].BuildMeterCalibFactor(calibFactorRel.Value);
|
||||
_calibFactor[channel - 1].IsCalculated = true;
|
||||
|
||||
Logger.Info($"Slot:{Slot}, Channel:{channel} - New calibration factor({_calibFactor[channel - 1].GetRelativeCalibFactor()}rel/{calibFactorRel})");
|
||||
|
||||
Logger.Info($"Slot:{Slot}, Channel:{channel} - Calc /{_calibFactor[channel - 1].GetMeterRawCalibFactor()} * {calibFactorRel.Value}) -> UInt16");
|
||||
|
||||
|
||||
//Setup the required tolerance value to check against
|
||||
//plus/minus x% tolerance allowed
|
||||
calib.CalibFactorTolerancePercent = maxCalibFactorTolerancePercent;
|
||||
|
||||
if (calib.IsCalibFactorInTolerance(calibFactorRel.Value))
|
||||
{
|
||||
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var warnMessage = $"Slot:{Slot}, Channel:{channel} - " +
|
||||
$"Calibration factor is out of range({calibFactorRel.Value}rel)";
|
||||
Logger.Warn(warnMessage);
|
||||
// throw new ApplicationException(warnMessage);
|
||||
}
|
||||
|
||||
|
||||
var t = new JustageResults
|
||||
{
|
||||
pcbId = PcbId,
|
||||
p1Target = reqDeviationPercent,
|
||||
p1Value = _calibFactor[0].GetMeterRawCalibFactor(),
|
||||
p2Target = reqDeviationPercent,
|
||||
p2Value = _calibFactor[1].GetMeterRawCalibFactor(),
|
||||
p3Target = reqDeviationPercent,
|
||||
p3Value = _calibFactor[2].GetMeterRawCalibFactor(),
|
||||
dt = DateTime.UtcNow,
|
||||
testrunNr = testrunNr
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var tmpUrl = "http://10.49.40.25/MeterProcessState/api/TestBench/SetCalibrationValues";
|
||||
Logger.Info($"Request Url: {tmpUrl}");
|
||||
//ToDO: Update to service URl
|
||||
|
||||
LocalWebRequest.PostAsJson<JustageResults>(t, tmpUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Request Url: {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetCalibFactorsAllChannels(Boolean justLog = false)
|
||||
{
|
||||
WriteRegister<Byte>(Register.Genesisflow.SampleRate, 2, checkRegister: true);
|
||||
WriteRegister<UInt16>(Register.Genesisflow.TriggerIdle, 0x1234);
|
||||
|
||||
for (var channel = 0; channel < MeterConfig.CalibChannels; channel++)
|
||||
{
|
||||
if (_calibFactor[channel].IsCalculated == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (justLog)
|
||||
{
|
||||
Logger.Warn($"Slot:{Slot} - Calculated calibration factors but not stored to registers");
|
||||
}
|
||||
else
|
||||
{
|
||||
var registerRawCalibFactor = _calibFactor[channel].GetMeterRawCalibFactor();
|
||||
var resultWrite = WriteRegister(_calibFactor[channel].RegisterToStoreCalibFactor,
|
||||
registerRawCalibFactor, checkRegister: true);
|
||||
Logger.Info($"Slot:{Slot}, Channel:{channel} - Stored calibration factor({_registersToStoreCalibFactor[channel]})");
|
||||
|
||||
//if (!string.IsNullOrEmpty(SerialNumber) && CurrentActionText.Contains("PG"))
|
||||
//{
|
||||
|
||||
// var pathMain = NLogHelper.GetPath(_logger);
|
||||
// var pathRaw = NLogHelper.GetPath(((LedSerialPort)StreamingPort).GetRawLogger());
|
||||
|
||||
// var basePath = Path.GetDirectoryName(pathMain);
|
||||
|
||||
// //
|
||||
|
||||
|
||||
// var testRunString = CurrentActionText.Replace("PG", "");
|
||||
//
|
||||
if (resultWrite)
|
||||
{
|
||||
Logger.Warn($"Set calibration went wrong {_calibFactor[channel].RegisterToStoreCalibFactor}, with {registerRawCalibFactor}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WriteRegister(Register.Genesisflow.ResetAccumulators, true);
|
||||
//WriteRegister<UInt16>(Register.Genesisflow.ForwardArrow, 0, checkRegister: true);
|
||||
WriteRegister<UInt16>(Register.Genesisflow.StoreCalibration, 1);
|
||||
|
||||
Logger.Info($"Slot:{Slot} - StoreCalibration {RegisterConverter.ByteArrayToValue<UInt16>(ReadRegister(Register.Genesisflow.StoreCalibration))}");
|
||||
WriteRegister<UInt16>(Register.Genesisflow.TriggerActive, 1);
|
||||
Logger.Info($"Slot:{Slot} - Set forward arrow of LCD, reset accumulators, set sample rate to 2Hz");
|
||||
WriteRegister<Byte>(Register.Genesisflow.SampleRate, 10, checkRegister: true);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (Enumerable.Any(GetRegistersDic(), a => a.Key.RegisterName == "GENESISFLOW_DelayedLedOff"))
|
||||
{
|
||||
WriteRegister("GENESISFLOW_DelayedLedOff", 60 * 60 * 2, true);
|
||||
Logger.Info($"Slot:{Slot} - GENESISFLOW_DelayedLedOff to {60 * 60 * 2}S");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - GENESISFLOW_DelayedLedOff is not present");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Logger.Info($"Slot:{Slot} - {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.Const;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
using Xylem.Common.Metrology.Measurements.Consts;
|
||||
using LedMode = TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore.Consts.LedMode;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.GenesisCore
|
||||
{
|
||||
public partial class GenesisMeter
|
||||
{
|
||||
/// <summary>
|
||||
/// List of ongoing measurements, base- and calibration-measurements
|
||||
/// </summary>
|
||||
private List<IMeasurement> _listOfIMeasurement = new List<IMeasurement>();
|
||||
|
||||
/// <summary>
|
||||
/// All channels required to process
|
||||
/// </summary>
|
||||
public Boolean AllChannelsRequired = true;
|
||||
|
||||
/// <summary>
|
||||
/// Quality watch mode can be used to decode intermediate records and check
|
||||
/// for actual quality of the measurements.
|
||||
/// </summary>
|
||||
public Boolean QualityWatchMode;
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Perpetration of Measurement
|
||||
/// SampleRate 10 and Led mode Test
|
||||
/// </summary>
|
||||
public void InitMeasurement()
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - Init measurement");
|
||||
PreMeasurement();
|
||||
}
|
||||
|
||||
private void PreMeasurement()
|
||||
{
|
||||
if (!SkipPreparationForTestBench)
|
||||
{
|
||||
//SkipPreparationForTestBench = true;
|
||||
//TODO set display unit
|
||||
//TODO calculated overflow volume for display
|
||||
WriteRegister<Byte>(Register.Genesisflow.SampleRate, 0x08, checkRegister: true);
|
||||
WriteRegister(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestAndCalibData, checkRegister: true);
|
||||
WriteRegister("GENESISFLOW_SealDisplay", 0, true, true);
|
||||
|
||||
try
|
||||
{
|
||||
var displayState = ReadRegister(Register.Genesisflow.TriggerIdle);
|
||||
if (displayState == null)
|
||||
{
|
||||
displayState = ReadRegister(Register.Genesisflow.TriggerIdle);
|
||||
if (displayState == null)
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - Not able to read display state");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var displayStateString = ByteStyler.ToString(displayState);
|
||||
|
||||
|
||||
if (displayStateString.Substring(0, 2) != "FF" || displayStateString.Substring(0, 5) == "FF-55")
|
||||
{
|
||||
WriteRegister(Register.Genesisflow.TriggerIdle, 0, true, true);
|
||||
displayState = ReadRegister(Register.Genesisflow.TriggerIdle);
|
||||
displayStateString = ByteStyler.ToString(displayState);
|
||||
if (displayStateString != "00-00-00-00")
|
||||
{
|
||||
WriteRegister(Register.Genesisflow.TriggerActive, 1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog($"meter not active because display code has an error on code:{displayStateString}");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
|
||||
WriteRegister("GENESISFLOW_DisplayPow10", (new Byte[] { 0x00, 0x00, 0x00, 0xFA }).Reverse().ToArray());
|
||||
//WriteRegister(Register.Genesisflow.StoreCalibration, 1);
|
||||
//WriteRegister(Register.Genesisflow.StoreConfiguration, 1);
|
||||
|
||||
try
|
||||
{
|
||||
if (Enumerable.Any(GetRegistersDic(), a => a.Key.RegisterName == "GENESISFLOW_DelayedLedOff"))
|
||||
{
|
||||
WriteRegister("GENESISFLOW_DelayedLedOff", 60 * 60 * 2, false);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog($"wait for measurement is starting");
|
||||
}
|
||||
ProcessStatus = ProcessState.WaitForMeasurement;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StartMeasurement()
|
||||
{
|
||||
_listOfIMeasurement = new List<IMeasurement>
|
||||
{
|
||||
new BaseMeasurement(Slot, typeof(FlowTestRecord), IntermediateUpdateTimeS)
|
||||
};
|
||||
|
||||
//add channels for calibration measurement
|
||||
for (var i = 1; i <= MeterConfig.CalibChannels; i++)
|
||||
{
|
||||
_listOfIMeasurement.Add(new CalibrationMeasurement(Slot, typeof(CalibrationRecord), IntermediateUpdateTimeS, i));
|
||||
}
|
||||
|
||||
foreach (var measurement in _listOfIMeasurement)
|
||||
{
|
||||
measurement.OnActionStateHasChanged += Measurement_ActionStateHasChanged;
|
||||
}
|
||||
|
||||
Logger.Info($"Slot:{Slot} - Start measurement");
|
||||
|
||||
ProcessStatus = ProcessState.MeasurementIsActive;
|
||||
_listOfIMeasurement.ForEach(m => m.MeasurementState = MeasurementStates.IsWaitingForStartData);
|
||||
SyncStreamingBuffer(SyncMarkRecord.SyncStart);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StopMeasurement()
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - Stop measurement");
|
||||
ProcessStatus = ProcessState.MeasurementIsDone;
|
||||
_listOfIMeasurement.ForEach(m => m.MeasurementState = MeasurementStates.IsWaitingForEndData);
|
||||
SyncStreamingBuffer(SyncMarkRecord.SyncEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Testing the flow direction
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Boolean CheckChannelFlowDirection()
|
||||
{
|
||||
Boolean? dirPositive = null;
|
||||
foreach (var cali in _listOfIMeasurement.Where(m => m.GetType() == typeof(CalibrationRecord)))
|
||||
{
|
||||
var result = cali.GetIntermediateMeasurementResult();
|
||||
var channelDirPositive = result.DutVolumeCm > 0.0;
|
||||
|
||||
if (!dirPositive.HasValue)
|
||||
{
|
||||
dirPositive = channelDirPositive;
|
||||
}
|
||||
if (dirPositive != channelDirPositive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// the first measurement is ALWAYS a FlowTestRecord due to the underlying<see cref="GetAllMeasurementResults"/> routine logic.
|
||||
/// </summary>
|
||||
public MeasurementResults GetMainMeasurementResult(Double? refVolume, Double? refTimeS, Boolean intermediateMeasurement = false, MeasurementDirection dir = MeasurementDirection.TakeBoth)
|
||||
{
|
||||
if (!intermediateMeasurement && GetMeasurementState(0) != MeasurementStates.IsCompleted)
|
||||
{
|
||||
throw new ApplicationException("Measurement is not completed");
|
||||
}
|
||||
return GetAllMeasurementResults(refVolume, refTimeS, intermediateMeasurement, 0).First();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The first measurement is ALWAYS a FlowTestRecord.
|
||||
/// </summary>
|
||||
public List<MeasurementResults> GetAllMeasurementResults(Double? refVolume, Double? refTimeS, Boolean intermediateMeasurement = false, Int32? channel = null, MeasurementDirection dir = MeasurementDirection.TakeBoth)
|
||||
{
|
||||
//
|
||||
if (!intermediateMeasurement && GetMeasurementState(channel) != MeasurementStates.IsCompleted)
|
||||
{
|
||||
throw new ApplicationException("Measurement is not completed");
|
||||
}
|
||||
var mainMeasurement = _listOfIMeasurement.FirstOrDefault(m => m.GetType() == typeof(FlowTestRecord));
|
||||
|
||||
if (mainMeasurement == null)
|
||||
{
|
||||
throw new ApplicationException("Can not find an ongoing measurement");
|
||||
}
|
||||
mainMeasurement.FlowDirectionforCalculatingVol = dir;
|
||||
var results = new List<MeasurementResults>();
|
||||
var mainResult = intermediateMeasurement
|
||||
? mainMeasurement.GetIntermediateMeasurementResult(refVolume, refTimeS)
|
||||
: mainMeasurement.GetFinalMeasurementResult(refVolume, refTimeS);
|
||||
results.Add(mainResult);
|
||||
Logger.Info($"Slot:{Slot}, Channel:{mainMeasurement.GetChannel()} - MeasuredTime({mainResult.DutTimeS}s), " +
|
||||
$"MeasuredVolume({mainResult.DutVolumeCm}Qm)");
|
||||
|
||||
foreach (var otherMeasurement in _listOfIMeasurement.Where(m => m.GetType() != typeof(FlowTestRecord)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var otherResults = intermediateMeasurement
|
||||
? otherMeasurement.GetIntermediateMeasurementResult(refVolume, refTimeS)
|
||||
: otherMeasurement.GetFinalMeasurementResult(refVolume, refTimeS);
|
||||
Logger.Info($"Slot:{Slot}, Channel:{otherMeasurement.GetChannel()} - ChannelTime({otherResults.DutTimeS}s), " +
|
||||
$"ChannelVolume({otherResults.DutVolumeCm}Qm)");
|
||||
results.Add(otherResults);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warn($"Slot:{Slot}, No Results for channel:{otherMeasurement.GetChannel()} Ex: {ex.Message}");
|
||||
if (channel == null)
|
||||
{
|
||||
throw new ApplicationException($"Can not read result from channel:{otherMeasurement.GetChannel() } Ex: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private void AddData(IMeasurementRecord newRecord)
|
||||
{
|
||||
|
||||
foreach (var measurement in _listOfIMeasurement)
|
||||
{
|
||||
if (measurement.GetType() != newRecord.GetType())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (measurement.GetChannel() == newRecord.GetChannel())
|
||||
{
|
||||
measurement.AddData(newRecord);
|
||||
}
|
||||
}
|
||||
|
||||
// when every measurement has state IsRunning or every measurement has state IsCompleted, the streaming buffer set to skip decoding
|
||||
if (_listOfIMeasurement.All(m => m.MeasurementState == MeasurementStates.IsRunning)
|
||||
|| _listOfIMeasurement.All(m => m.MeasurementState == MeasurementStates.IsCompleted))
|
||||
{
|
||||
SyncStreamingBuffer(QualityWatchMode
|
||||
? SyncMarkRecord.DecodeIntermediateQuality
|
||||
: SyncMarkRecord.SkipDecoding);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Measurement_ActionStateHasChanged(Object sender, EventArgs e)
|
||||
{
|
||||
SyncStreamingBuffer(SyncMarkRecord.DecodeIntermediate);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeasurementStates GetMeasurementState(Int32? onlyChannelNr = null)
|
||||
{
|
||||
Logger.Trace($"Slot:{Slot} - Get measurement state");
|
||||
if (!_listOfIMeasurement.Any())
|
||||
{
|
||||
return MeasurementStates.NotStarted;
|
||||
}
|
||||
|
||||
if (onlyChannelNr.HasValue)
|
||||
{
|
||||
var measurement = _listOfIMeasurement.First(f => f.GetChannel() == onlyChannelNr.Value);
|
||||
return measurement.GetMeasurementState();
|
||||
}
|
||||
return _listOfIMeasurement.Min(m => m.MeasurementState);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean RequestIntermediateMeasurementState(Int32? onlyChannelNr = null)
|
||||
{
|
||||
Logger.Trace($"Slot:{Slot} - Get measurement state");
|
||||
if (!_listOfIMeasurement.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Boolean? ret = null;
|
||||
foreach (var item in _listOfIMeasurement)
|
||||
{
|
||||
if (!onlyChannelNr.HasValue || item.GetChannel() == onlyChannelNr.Value)
|
||||
{
|
||||
var measurement = _listOfIMeasurement.First(f => onlyChannelNr != null && f.GetChannel() == onlyChannelNr.Value);
|
||||
if ((measurement.MeasurementState == MeasurementStates.IsRunning
|
||||
|| measurement.MeasurementState == MeasurementStates.IsWaitingForIntermediateData))
|
||||
{
|
||||
measurement.RequestIntermediateRecord();
|
||||
if (!ret.HasValue)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret.HasValue ? ret.Value : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+24132
File diff suppressed because it is too large
Load Diff
+313
@@ -0,0 +1,313 @@
|
||||
{
|
||||
"_comment": "Auto generated from 'Configuration.xls' - DO NOT MANUALLY EDIT THIS TABLE",
|
||||
"CONFIGEXCHANGE_Privilege": {"type": "uint8_t", "id": 1024, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_Password": {"type": "uint96_t", "id": 1025, "privilege": {"lvl1": "WO", "lvl2": "WO", "lvl3": "WO", "lvl4": "WO", "lvl5": "WO", "lvl6": "WO", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"CONFIGEXCHANGE_FOpen": {"type": "RPC", "id": 1026, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FClose": {"type": "RPC", "id": 1027, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FRead": {"type": "RPC", "id": 1028, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FWrite": {"type": "RPC", "id": 1029, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FSeek": {"type": "RPC", "id": 1030, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FTell": {"type": "RPC", "id": 1031, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_Remove": {"type": "RPC", "id": 1032, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FEOF": {"type": "RPC", "id": 1033, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_Catalogue": {"type": "RPC", "id": 1034, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_PCBSerialNumber": {"type": "string", "id": 1036, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CONFIGEXCHANGE_ConfigAccessRights": {"type": "uint16_t", "id": 1037, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CONFIGEXCHANGE_FFlush": {"type": "RPC", "id": 1038, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AlarmStatus0": {"type": "uint32_t", "id": 2304, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus1": {"type": "uint32_t", "id": 2305, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_TriggerAlarmCancel": {"type": "uint32_t", "id": 2306, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AlarmStatus2": {"type": "uint32_t", "id": 2307, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus3": {"type": "uint32_t", "id": 2308, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus4": {"type": "uint32_t", "id": 2309, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus5": {"type": "uint32_t", "id": 2310, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus6": {"type": "uint32_t", "id": 2311, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmStatus7": {"type": "uint32_t", "id": 2312, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_AlarmEnableMask": {"type": "uint32_t", "id": 2313, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AlarmBroadcastMask": {"type": "uint32_t", "id": 2314, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AlarmVisualMask": {"type": "uint32_t", "id": 2315, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AlarmVisualAutoClearMask": {"type": "uint32_t", "id": 2316, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_ExcessFlowVolumeThreshold": {"type": "uint32_t", "id": 2317, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_LeakTimeThreshold": {"type": "uint32_t", "id": 2318, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_ReverseFlowTimeThreshold": {"type": "uint16_t", "id": 2319, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_Locale": {"type": "uint16_t", "id": 2322, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_AppArrangement": {"type": "enum8", "id": 2323, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_RebootCount": {"type": "uint32_t", "id": 2324, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_ExcessFlowTimeThreshold": {"type": "uint32_t", "id": 2325, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_LeakFlowThreshold": {"type": "uint32_t", "id": 2326, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_MfgCharge": {"type": "uint32_t", "id": 2327, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_TemperatureHighThreshold": {"type": "int32_t", "id": 2328, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_TemperatureHighDelay": {"type": "uint32_t", "id": 2329, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_TemperatureLowThreshold": {"type": "int32_t", "id": 2330, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_TemperatureLowDelay": {"type": "uint32_t", "id": 2331, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_PressureHighThreshold": {"type": "int32_t", "id": 2332, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_PressureHighDelay": {"type": "uint32_t", "id": 2333, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_PressureLowThreshold": {"type": "int32_t", "id": 2334, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_PressureLowDelay": {"type": "uint32_t", "id": 2335, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_StoreConfiguration": {"type": "uint32_t", "id": 2336, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_SerialNumber": {"type": "string", "id": 2337, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_BackupCalendarSeconds": {"type": "time_t", "id": 2338, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "NA", "lvl8": "NA"}},
|
||||
"CUSTOMER_InstallationTime": {"type": "time_t", "id": 2339, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_LocaleDecimalPoint": {"type": "string", "id": 2340, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_LocaleThousandsSeparator": {"type": "string", "id": 2341, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"CUSTOMER_InternalLoginTest": {"type": "uint32_t", "id": 2342, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_NoFlowLimit": {"type": "uint32_t", "id": 2343, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"CUSTOMER_NoFlowAlarmResetHysteresis": {"type": "uint32_t", "id": 2344, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FLEXNETSERIAL_UpgState": {"type": "uint32_t", "id": 6656, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FLEXNETSERIAL_FwdlState": {"type": "uint32_t", "id": 6657, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_GP30Test": {"type": "uint32_t", "id": 2560, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_LCDTest": {"type": "uint32_t", "id": 2561, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_Iloop": {"type": "uint32_t", "id": 2562, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_Pulse": {"type": "uint32_t", "id": 2563, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_Pressure": {"type": "uint32_t", "id": 2564, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_BatteryVoltage": {"type": "uint32_t", "id": 2565, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"FUNCTEST_SupplyVoltage": {"type": "uint32_t", "id": 2566, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"FUNCTEST_Temperature": {"type": "int16_t", "id": 2567, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"FUNCTEST_RFID": {"type": "uint32_t", "id": 2568, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_OpticalOutput": {"type": "uint32_t", "id": 2569, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_Radio": {"type": "uint32_t", "id": 2570, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_MultiTest": {"type": "uint16_t", "id": 2571, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_NFCUID": {"type": "uint64_t", "id": 2572, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"FUNCTEST_CPUTest": {"type": "uint32_t", "id": 2573, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_SampleRate": {"type": "uint8_t", "id": 3840, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlUp1": {"type": "int8_t", "id": 3841, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlUp2": {"type": "int8_t", "id": 3842, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlUp3": {"type": "int8_t", "id": 3843, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlDown1": {"type": "int8_t", "id": 3844, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlDown2": {"type": "int8_t", "id": 3845, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitLvlDown3": {"type": "int8_t", "id": 3846, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_StartHit": {"type": "uint8_t", "id": 3847, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_AmplitudePeakDetectEnd": {"type": "uint8_t", "id": 3848, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_NumFirePulses": {"type": "uint8_t", "id": 3849, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_DisplayPow10": {"type": "int8_t", "id": 3850, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_DisplayUnits": {"type": "enum8", "id": 3851, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MeterSize": {"type": "enum8", "id": 3852, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_CalFactor1": {"type": "uint16_t", "id": 3853, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_CalFactor2": {"type": "uint16_t", "id": 3854, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_CalFactor3": {"type": "uint16_t", "id": 3855, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ZeroOffset1": {"type": "int32_t", "id": 3856, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ZeroOffset2": {"type": "int32_t", "id": 3857, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ZeroOffset3": {"type": "int32_t", "id": 3858, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ScaledBilling": {"type": "int64_t", "id": 3859, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"GENESISFLOW_ResetAccumulators": {"type": "bool_t", "id": 3860, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"GENESISFLOW_ForwardArrow": {"type": "enum8", "id": 3861, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_LedMode": {"type": "enum8", "id": 3862, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_StoreCalibration": {"type": "uint32_t", "id": 3863, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_UnscaledFwd": {"type": "uint64_t", "id": 3864, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_UnscaledRev": {"type": "uint64_t", "id": 3865, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_LowFlowThreshold": {"type": "uint32_t", "id": 3866, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_LowFlowMaxPeriod": {"type": "uint32_t", "id": 3867, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_UpdateThreshold": {"type": "uint32_t", "id": 3868, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ArrowThreshold": {"type": "uint32_t", "id": 3869, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FireBuffer1": {"type": "uint8_t", "id": 3870, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FireBuffer2": {"type": "uint8_t", "id": 3871, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FireBuffer3": {"type": "uint8_t", "id": 3872, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_TriggerActive": {"type": "bool_t", "id": 3873, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_TriggerIdle": {"type": "uint16_t", "id": 3874, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxValidDeltaToF": {"type": "uint32_t", "id": 3875, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxValidToF": {"type": "uint32_t", "id": 3876, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MinValidToF": {"type": "uint32_t", "id": 3877, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitPercent1": {"type": "uint8_t", "id": 3878, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitPercent2": {"type": "uint8_t", "id": 3879, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitPercent3": {"type": "uint8_t", "id": 3880, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitShift": {"type": "uint8_t", "id": 3881, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitMinimum": {"type": "uint8_t", "id": 3882, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ToFErrorLimit": {"type": "uint32_t", "id": 3883, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FirstHitUpdatePeriod": {"type": "uint8_t", "id": 3884, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_PipeFillingDelay": {"type": "uint8_t", "id": 3885, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ToFTempOffset1": {"type": "int32_t", "id": 3886, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ToFTempOffset2": {"type": "int32_t", "id": 3887, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ToFTempOffset3": {"type": "int32_t", "id": 3888, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_ToFTempCalibrate": {"type": "int32_t", "id": 3889, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"GENESISFLOW_StoreConfiguration": {"type": "uint32_t", "id": 3890, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_SealDisplay": {"type": "bool_t", "id": 3891, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_TriggerTest": {"type": "bool_t", "id": 3892, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxValidAmplitude": {"type": "uint32_t", "id": 3893, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MinValidAmplitude": {"type": "uint32_t", "id": 3894, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_HardErrorLimit": {"type": "uint16_t", "id": 3895, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_Timeout": {"type": "uint8_t", "id": 3896, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxDeltaToFDeviation": {"type": "uint32_t", "id": 3897, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxTempRange": {"type": "uint32_t", "id": 3898, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_MaxDeltaToFRange": {"type": "uint32_t", "id": 3899, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_LookupFileCrc": {"type": "uint32_t", "id": 3900, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_DisplayLeadingZeros": {"type": "bool_t", "id": 3901, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_InstallationCorrectionEnabled": {"type": "bool_t", "id": 3902, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_InstallationDetectionThreshold": {"type": "uint32_t", "id": 3903, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_InstallationType": {"type": "uint32_t", "id": 3904, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_InstallationDetectionStatus": {"type": "uint8_t", "id": 3905, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_FractionalBars": {"type": "bool_t", "id": 3906, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"GENESISFLOW_CalibrationCount": {"type": "uint8_t", "id": 3907, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"GENESISFLOW_DelayedLedOff": {"type": "uint16_t", "id": 3908, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "WO", "lvl6": "WO", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"GENESISFLOW_DisplayVolumeRow2": {"type": "bool_t", "id": 3909, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_PulseReportRate": {"type": "enum8", "id": 5120, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_AdapterPresenceLimit": {"type": "uint8_t", "id": 5121, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_PulseSequence": {"type": "uint8_t", "id": 5122, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_StoreConfiguration": {"type": "uint32_t", "id": 5123, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_AMRDigits": {"type": "uint8_t", "id": 5124, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_AMROffset": {"type": "int8_t", "id": 5125, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_UI1203Fields": {"type": "uint16_t", "id": 5126, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_MfgDate": {"type": "time_t", "id": 5127, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_DisplayAMRDigits": {"type": "bool_t", "id": 5128, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"IRDA_AdapterID": {"type": "string", "id": 5129, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"IRDA_AdapterFwVersion": {"type": "uint16_t", "id": 5130, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"IRDA_ExtendedResolution": {"type": "bool_t", "id": 5131, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"LOGGER_Quota": {"type": "uint32_t", "id": 2048, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"LOGGER_Drive": {"type": "uint8_t", "id": 2049, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"LOGGER_TriggerLogFlush": {"type": "bool_t", "id": 2050, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"LOGGER_StoreConfiguration": {"type": "uint32_t", "id": 2051, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_ILoopMaxFlowRate": {"type": "uint32_t", "id": 4608, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_StoreConfiguration": {"type": "uint32_t", "id": 4609, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PulseWeight": {"type": "uint32_t", "id": 4610, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PulseMode": {"type": "enum8", "id": 4611, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PulseLength": {"type": "enum8", "id": 4612, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_FlowUnits": {"type": "enum8", "id": 4613, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_FlowPoint": {"type": "enum8", "id": 4614, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_ILoopRate": {"type": "uint32_t", "id": 4615, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_TemperatureUnits": {"type": "enum8", "id": 4616, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureUnits": {"type": "enum8", "id": 4617, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureRate": {"type": "uint32_t", "id": 4618, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureOffset": {"type": "int32_t", "id": 4619, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressurePresent": {"type": "bool_t", "id": 4620, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureMeasure": {"type": "int32_t", "id": 4621, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_LatestFlowRate": {"type": "int32_t", "id": 4622, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_GenerateFwdPulses": {"type": "uint8_t", "id": 4623, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"METROLOGYASST_GenerateRevPulses": {"type": "uint8_t", "id": 4624, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"METROLOGYASST_PulseEvenDistribution": {"type": "bool_t", "id": 4625, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PulseResolution": {"type": "uint8_t", "id": 4626, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"METROLOGYASST_PressureCalibration": {"type": "int32_t", "id": 4627, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_DisplayEnable": {"type": "uint32_t", "id": 4628, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RW", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureFlowRateCorrectionA": {"type": "int32_t", "id": 4629, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"METROLOGYASST_PressureFlowRateCorrectionB": {"type": "int32_t", "id": 4630, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"NA2WALARMS_StoreConfiguration": {"type": "uint32_t", "id": 5888, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"NA2WALARMS_PredefEnable": {"type": "uint32_t", "id": 5889, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"NA2WLOGGER_StoreConfiguration": {"type": "uint32_t", "id": 5632, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "RW", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"NA2WLOGGER_LimitLogSize": {"type": "uint32_t", "id": 5633, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"NFC_EraseRMA": {"type": "bool_t", "id": 5376, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RW"}},
|
||||
"NFC_ForceUpdate": {"type": "uint8_t", "id": 5377, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"OPTICALPORT_BaudRateCapabilities": {"type": "uint32_t", "id": 1280, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"OPTICALPORT_PacketSizeCapabilities": {"type": "uint32_t", "id": 1281, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"OPTICALPORT_ProtocolVersion": {"type": "uint16_t", "id": 1282, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"OPTICALPORT_BaudRateSelected": {"type": "uint32_t", "id": 1283, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"OPTICALPORT_PacketSizeSelected": {"type": "uint32_t", "id": 1284, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"OPTICALPORT_ExternalUartControl": {"type": "uint8_t", "id": 1285, "privilege": {"lvl1": "WO", "lvl2": "WO", "lvl3": "WO", "lvl4": "WO", "lvl5": "WO", "lvl6": "WO", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"PERIODICLOG_DataLogContents": {"type": "uint32_t", "id": 4352, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_DataLogPeriod": {"type": "uint16_t", "id": 4353, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_AverageFlowPeriod": {"type": "uint16_t", "id": 4354, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_FixedDateReadingContents": {"type": "uint32_t", "id": 4355, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_FixedDateDayOfMonth": {"type": "uint8_t", "id": 4356, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_PeriodicLogLifeTimeCounter": {"type": "uint32_t", "id": 4357, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"PERIODICLOG_ResetCounter": {"type": "uint32_t", "id": 4358, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_BatteryVoltage": {"type": "uint16_t", "id": 256, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_BatteryManufacturer": {"type": "string", "id": 257, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_BatterySize": {"type": "enum8", "id": 258, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_BatteryQuantity": {"type": "uint8_t", "id": 260, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_BatteryRatedVoltage": {"type": "uint8_t", "id": 261, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_BatteryVoltageMinThreshold": {"type": "uint8_t", "id": 263, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_BatterySelection": {"type": "uint8_t", "id": 264, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_TotalUsedCharge": {"type": "uint64_t", "id": 265, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_TotalUsedSeconds": {"type": "uint32_t", "id": 266, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_WarnFromClamp": {"type": "uint32_t", "id": 267, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_BatteryMilliAHrRating": {"type": "uint16_t", "id": 268, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"POWERMON_StoreConfiguration": {"type": "uint32_t", "id": 269, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_CriticalRepeatLimit": {"type": "uint8_t", "id": 270, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"POWERMON_RemainingSeconds": {"type": "uint32_t", "id": 271, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"SENSUSRADIO_TxInterval": {"type": "uint16_t", "id": 4096, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_OmTxInterval": {"type": "uint16_t", "id": 4097, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_LatInterval": {"type": "uint8_t", "id": 4098, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_WakeupInterval": {"type": "uint8_t", "id": 4099, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_MbusState": {"type": "uint8_t", "id": 4100, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_FrequencyIndicator": {"type": "uint16_t", "id": 4101, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_FrequencyOffset": {"type": "int16_t", "id": 4102, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PowerLevel": {"type": "uint8_t", "id": 4103, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_SystemState": {"type": "uint8_t", "id": 4105, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_RadioAddress": {"type": "uint32_t", "id": 4106, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_UtcTimeOffset": {"type": "uint32_t", "id": 4107, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_SentBytesCounter": {"type": "uint16_t", "id": 4108, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ReceivedBytesCounter": {"type": "uint16_t", "id": 4109, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ResetCounter": {"type": "uint16_t", "id": 4110, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_BootLoaderState": {"type": "uint8_t", "id": 4111, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_LeakFlowThreshold": {"type": "uint16_t", "id": 4112, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_LeakFlowTimeThreshold": {"type": "uint16_t", "id": 4113, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_BrokenPipeFlowThreshold": {"type": "uint16_t", "id": 4114, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_BrokenPipeFlowTimeThreshold": {"type": "uint16_t", "id": 4115, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureMaxThreshold": {"type": "uint8_t", "id": 4116, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureMinThreshold": {"type": "uint8_t", "id": 4117, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureLimitTimeMaxThreshold": {"type": "uint16_t", "id": 4118, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureLimitTimeMinThreshold": {"type": "uint16_t", "id": 4119, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureMeasurePeriod": {"type": "uint16_t", "id": 4120, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureUnit": {"type": "uint8_t", "id": 4121, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureGaugeOffset": {"type": "uint16_t", "id": 4122, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureMaxThreshold": {"type": "uint8_t", "id": 4123, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureMinThreshold": {"type": "uint8_t", "id": 4124, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureTimeMaxThreshold": {"type": "uint16_t", "id": 4125, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureTimeMinThreshold": {"type": "uint16_t", "id": 4126, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureMeasurePeriod": {"type": "uint16_t", "id": 4127, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TemperatureUnit": {"type": "uint8_t", "id": 4128, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PulseOutWidth": {"type": "uint16_t", "id": 4129, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PulseOutDivisor": {"type": "uint16_t", "id": 4130, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PulseOutMode": {"type": "uint8_t", "id": 4131, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_CurrentLoopMax": {"type": "uint16_t", "id": 4132, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_CurrentLoopSource": {"type": "uint8_t", "id": 4133, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_MainAlarmMask": {"type": "uint8_t", "id": 4134, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ExtendedAlarmMask": {"type": "uint8_t", "id": 4135, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_HistoricalAlarmsDays": {"type": "uint8_t", "id": 4136, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TestModeTime": {"type": "uint16_t", "id": 4139, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_EncryptionKey": {"type": "uint32_t", "id": 4140, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_Authentification": {"type": "uint32_t", "id": 4141, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_UpgFWVersion": {"type": "uint16_t", "id": 4142, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_CustomerText": {"type": "uint32_t", "id": 4143, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_RadioLastReadTime": {"type": "uint32_t", "id": 4144, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_LowBatDateTime": {"type": "uint32_t", "id": 4145, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_VeryLowBatDateTime": {"type": "uint32_t", "id": 4146, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_Unit": {"type": "uint8_t", "id": 4147, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ExtendedUnitFlags": {"type": "uint8_t", "id": 4148, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_OTAControlFlags": {"type": "uint8_t", "id": 4149, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_Tfx_Structure": {"type": "uint32_t", "id": 4150, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_Dewa_Structure": {"type": "uint32_t", "id": 4151, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_DataLogContents": {"type": "uint32_t", "id": 4152, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_DataLogPeriod": {"type": "uint16_t", "id": 4153, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_AverageFlowPeriod": {"type": "uint16_t", "id": 4154, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_FixedDateReadingContents": {"type": "uint32_t", "id": 4155, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_FixedDateDayOfMonth": {"type": "uint8_t", "id": 4156, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_MetroRadioLifeTimeCounter": {"type": "uint32_t", "id": 4157, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PowerLevelOption": {"type": "uint8_t", "id": 4158, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ImpedanceCodeNew": {"type": "uint16_t", "id": 4159, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ImpedanceCodeOption": {"type": "uint16_t", "id": 4160, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_IrDAModulePresent": {"type": "bool_t", "id": 4161, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_StoreConfiguration": {"type": "bool_t", "id": 4162, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_LifeTimeSeconds": {"type": "uint32_t", "id": 4163, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_DutyCycleCredit": {"type": "uint32_t", "id": 4164, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_ActivityCredit": {"type": "uint32_t", "id": 4165, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup1": {"type": "uint32_t", "id": 4166, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup2": {"type": "uint32_t", "id": 4167, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup3": {"type": "uint32_t", "id": 4168, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup4": {"type": "uint32_t", "id": 4169, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PressureCalibration": {"type": "uint32_t", "id": 4170, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TfxSecondaryChannelInfo_1": {"type": "uint32_t", "id": 4171, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_TfxSecondaryChannelInfo_2": {"type": "uint32_t", "id": 4172, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_OmsLastMessageCounter": {"type": "uint32_t", "id": 4173, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup5": {"type": "uint32_t", "id": 4174, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SENSUSRADIO_PersistenceGroup6": {"type": "uint32_t", "id": 4175, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_TriggerUpgrade": {"type": "bool_t", "id": 0, "privilege": {"lvl1": "NA", "lvl2": "NA", "lvl3": "NA", "lvl4": "NA", "lvl5": "NA", "lvl6": "NA", "lvl7": "WO", "lvl8": "WO"}},
|
||||
"SYSTEM_CheckPresence": {"type": "RPC", "id": 1, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_PCBSerialNumber": {"type": "string", "id": 2, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"SYSTEM_CustomerSerialNumber0": {"type": "string", "id": 3, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CustomerSerialNumber1": {"type": "string", "id": 4, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CustomerSerialNumber2": {"type": "string", "id": 5, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CustomerSerialNumber3": {"type": "string", "id": 6, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_MonotonicSeconds": {"type": "uint32_t", "id": 7, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"SYSTEM_CalendarSeconds": {"type": "time_t", "id": 8, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CoreRevision": {"type": "string", "id": 9, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"SYSTEM_DriveCapacity": {"type": "uint32_t", "id": 10, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_ExitReason": {"type": "status_t", "id": 11, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CorePlatform": {"type": "uint16_t", "id": 12, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RO", "lvl8": "RO"}},
|
||||
"SYSTEM_CRC": {"type": "uint16_t", "id": 13, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_UpgradePermissions": {"type": "uint8_t", "id": 14, "privilege": {"lvl1": "RO", "lvl2": "RO", "lvl3": "RO", "lvl4": "RO", "lvl5": "RO", "lvl6": "RO", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"SYSTEM_CRC32": {"type": "uint32_t", "id": 15, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"TESTMANAGER_OutputFile": {"type": "string", "id": 25088, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"TESTMANAGER_TestNumber": {"type": "uint32_t", "id": 25089, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"TESTMANAGER_TestStatus": {"type": "enum8", "id": 25090, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"TESTMANAGER_TrapError": {"type": "uint32_t", "id": 25091, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"TESTMANAGER_TestParameter": {"type": "uint32_t", "id": 25092, "privilege": {"lvl1": "RW", "lvl2": "RW", "lvl3": "RW", "lvl4": "RW", "lvl5": "RW", "lvl6": "RW", "lvl7": "RW", "lvl8": "RW"}},
|
||||
"_comment": "end of table"
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments
|
||||
{
|
||||
/// <inheritdoc cref="EventArgs" />
|
||||
public abstract class BasePortDataEventArgs : EventArgs, IPortDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker for incoming record at time of the PC
|
||||
/// </summary>
|
||||
private DateTimeOffset _receivedTime = default(DateTimeOffset);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract Object GetData();
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void SetData(Object data);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetReceivedTime(DateTimeOffset receivedTime)
|
||||
{
|
||||
_receivedTime = receivedTime;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTimeOffset GetReceivedTime()
|
||||
{
|
||||
return _receivedTime;
|
||||
}
|
||||
|
||||
private SyncMarkRecord _syncMarkRecord;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetSyncMarkRecord(SyncMarkRecord syncMarkRecord)
|
||||
{
|
||||
_syncMarkRecord = syncMarkRecord;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public SyncMarkRecord GetSyncMarkRecord()
|
||||
{
|
||||
return _syncMarkRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Interface for port data event arguments
|
||||
/// </summary>
|
||||
public interface IPortDataEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Read data
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Object GetData();
|
||||
|
||||
/// <summary>
|
||||
/// Write data
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
void SetData(Object data);
|
||||
|
||||
/// <summary>
|
||||
/// Reading received time
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
DateTimeOffset GetReceivedTime();
|
||||
|
||||
/// <summary>
|
||||
/// Writing received time
|
||||
/// </summary>
|
||||
/// <param name="receivedTime"></param>
|
||||
void SetReceivedTime(DateTimeOffset receivedTime);
|
||||
|
||||
/// <summary>
|
||||
/// Setting the data marker
|
||||
/// </summary>
|
||||
/// <param name="syncMarkRecord"></param>
|
||||
void SetSyncMarkRecord(SyncMarkRecord syncMarkRecord);
|
||||
|
||||
/// <summary>
|
||||
/// Getting the data marker
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
SyncMarkRecord GetSyncMarkRecord();
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class ListBytePortDataEventArgs : BasePortDataEventArgs
|
||||
{
|
||||
private List<Byte> _data;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ListBytePortDataEventArgs(List<Byte> data, DateTimeOffset readTimeStampPc = default(DateTimeOffset),
|
||||
SyncMarkRecord syncMarkRecord = SyncMarkRecord.SkipDecoding)
|
||||
{
|
||||
_data = data;
|
||||
SetSyncMarkRecord(syncMarkRecord);
|
||||
SetReceivedTime(readTimeStampPc);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SetData(Object data)
|
||||
{
|
||||
_data = (List<Byte>)data;
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class StringPortDataEventArgs : BasePortDataEventArgs
|
||||
{
|
||||
private String _data;
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringPortDataEventArgs(String data, DateTimeOffset readTimeStampPc = default(DateTimeOffset),
|
||||
SyncMarkRecord syncMarkRecord = SyncMarkRecord.SkipDecoding)
|
||||
{
|
||||
_data = data;
|
||||
SetSyncMarkRecord(syncMarkRecord);
|
||||
SetReceivedTime(readTimeStampPc);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Object GetData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SetData(Object data)
|
||||
{
|
||||
_data = (String)data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore.EventArguments;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Interfaces.Ports.PortCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for Ports
|
||||
/// </summary>
|
||||
public interface IPort
|
||||
{
|
||||
/// <summary>
|
||||
/// event for record received, either bytes or string
|
||||
/// </summary>
|
||||
event EventHandler<BasePortDataEventArgs> OnRawRecordReceived;
|
||||
|
||||
/// <summary>
|
||||
/// event for record received, either bytes or string
|
||||
/// </summary>
|
||||
event EventHandler<BasePortDataEventArgs> OnRawRecordSendOut;
|
||||
/// <summary>
|
||||
/// set specific mark
|
||||
/// and flush or delete all incoming byte from buffer when SyncMarkRecord is <see cref="SyncMarkRecord.SyncStart"/> or
|
||||
/// <see cref="SyncMarkRecord.SyncEnd"/>
|
||||
/// </summary>
|
||||
/// <param name="syncMarkRecord"></param>
|
||||
void SynchronizeReceiveBuffer(SyncMarkRecord syncMarkRecord);
|
||||
|
||||
/// <summary>
|
||||
/// if the port needs stuff to open, always open for better logical handling
|
||||
/// </summary>
|
||||
void Open();
|
||||
|
||||
/// <summary>
|
||||
/// close and dispose all connections
|
||||
/// </summary>
|
||||
void Dispose();
|
||||
|
||||
/// <summary>
|
||||
/// indicates if the Port is open (also on Ports that did not have an open state)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Boolean IsOpen();
|
||||
|
||||
/// <summary>
|
||||
/// Write byte[] to the Stream/Port on Child Class
|
||||
/// wrapped with base class error handling
|
||||
/// </summary>
|
||||
/// <param name="data">Array of bytes to write</param>
|
||||
void PortWrite(Byte[] data);
|
||||
|
||||
/// <summary>
|
||||
/// discard all buffers
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Return the port name
|
||||
/// </summary>
|
||||
/// <returns>name of the port as string</returns>
|
||||
String GetPortName();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user