cancel btn for omni+ inspection

This commit is contained in:
Stoyan Zlatev
2023-11-20 09:05:17 +01:00
parent fa886a745f
commit 38486e0e5d
34 changed files with 813 additions and 433 deletions
@@ -5,7 +5,7 @@ using System;
using System.IO.Ports;
using System.Threading;
namespace OmniPlus.Connections
namespace OmniPlus
{
internal class IrdaConnection : SerialPortConnection
{
@@ -6,7 +6,7 @@ using System;
using System.IO;
using System.IO.Ports;
namespace OmniPlus.Connections
namespace OmniPlus
{
internal abstract class SerialPortConnection
{
@@ -5,7 +5,7 @@ using System;
using System.IO.Ports;
using System.Threading;
namespace OmniPlus.Connections
namespace OmniPlus
{
internal class UniProConnection : SerialPortConnection
{
+92
View File
@@ -0,0 +1,92 @@
namespace OmniPlus.Features
{
using System;
public class Alarm : FeatureRequest
{
const int LENGTH = 12;
public Alarm() : base(LENGTH)
{
}
public Alarm(byte[] response) : base(response, LENGTH)
{
}
public byte DeviceId
{
get => this.bytes[0];
protected set => this.bytes[0] = value;
}
public byte AlarmType
{
get => this.bytes[1];
protected set => this.bytes[1] = value;
}
public byte AlarmId
{
get => this.bytes[2];
protected set => this.bytes[2] = value;
}
public byte Channel
{
get => this.bytes[3];
protected set => this.bytes[3] = value;
}
/// <summary>
/// Rate = 0.25 * 1/60 * 1/1 = .0041666667 Gal/sec which converts into a Float32 of into 0x3B888889.
/// </summary>
public float FlowRateGal
{
get => BitConverter.ToSingle(this.bytes, 4);
set => BitConverter.GetBytes(value * (1 / 60) * (1 / 1)).CopyTo(this.bytes, 4);
}
/// <summary>
/// 0x00015180 (86400) seconds, which is 24 hours.
/// </summary>
public uint TimeLimit
{
get => BitConverter.ToUInt32(this.bytes, 8);
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 8);
}
}
public class LeakAlarm : Alarm
{
public LeakAlarm()
{
this.DeviceId = 0x00;
this.AlarmType = 0x04;
this.AlarmId = 0x01;
this.Channel = 0x00;
}
}
public class HighFlowAlarm : Alarm
{
public HighFlowAlarm()
{
this.DeviceId = 0x00;
this.AlarmType = 0x04;
this.AlarmId = 0x02;
this.Channel = 0x00;
}
}
public class ReverseFlowAlarm : Alarm
{
public ReverseFlowAlarm()
{
this.DeviceId = 0x00;
this.AlarmType = 0x05;
this.AlarmId = 0x04;
this.Channel = 0x00;
}
}
}
+57
View File
@@ -0,0 +1,57 @@
using System;
namespace OmniPlus.Features
{
public class AlarmSettings : FeatureRequest
{
const int LENGTH = 28;
public AlarmSettings() : base(LENGTH)
{
}
public AlarmSettings(byte[] response) : base(response, LENGTH)
{
}
public byte SensorVAndUsrAlarmsCount
{
get => this.bytes[0];
}
public byte ConfigVAndSequence
{
get => this.bytes[1];
}
public byte[] BitMask
{
get => this.bytes.Subarray(2, 3);
}
public byte PersistenceInDays
{
get => this.bytes[5];
}
public byte IdAndState
{
get => this.bytes[6];
}
public uint SecondsTriggered
{
get => BitConverter.ToUInt32(this.bytes, 7);
}
public uint SecondsEnded
{
get => BitConverter.ToUInt32(this.bytes, 11);
}
public string TypeAndData
{
get => BitConverter.ToString(this.bytes, 15, 13);
}
}
}
+49
View File
@@ -0,0 +1,49 @@
namespace OmniPlus.Features
{
public class AlarmsState : FeatureResponse
{
const int LENGTH = 27;
private readonly byte[] bytesI;
private readonly byte[] bytesII;
public AlarmsState(byte[] response) : base(response, LENGTH)
{
this.bytesI = this.I.Reverse().GetBits();
this.bytesII = this.II.Reverse().GetBits();
}
public byte Registers => this.bytes[0];
public byte[] I => this.bytes.Subarray(1, 6);
public byte[] II => this.bytes.Subarray(7, 6);
public byte III => this.bytes[13];
public byte IV => this.bytes[14];
public byte[] V => this.bytes.Subarray(15, 4);
public byte[] VI => this.bytes.Subarray(19, 2);
public byte[] VII => this.bytes.Subarray(21, 2);
public byte[] VIII => this.bytes.Subarray(23, 4);
public bool PreEnabledInactive
=> this.bytesI[8] + this.bytesI[9] == 1
&& this.bytesI[16] + this.bytesI[17] == 1
&& this.bytesI[24] + this.bytesI[25] == 1
&& this.bytesI[30] + this.bytesI[31] == 1
&& this.bytesI[32] + this.bytesI[33] == 1
&& this.bytesI[34] + this.bytesI[35] == 1
&& this.bytesI[42] + this.bytesI[43] == 1
&& this.bytesI[46] + this.bytesI[47] == 1;
public bool UsrEnabled
=> this.bytesI[38] + this.bytesI[39] == 1
&& this.bytesI[42] + this.bytesI[43] == 1
&& this.bytesI[44] + this.bytesI[45] == 1;
}
}
+6
View File
@@ -15,5 +15,11 @@
public BuildInfo(byte[] response) : base(response, LENGTH)
{
}
public static implicit operator BuildInfo(string value)
=> new BuildInfo
{
Value = value,
};
}
}
@@ -62,5 +62,13 @@
public ushort DataLogIntervalMins { get; set; }
public DeviceID DeviceID { get; set; }
public ManifacturingTime ManifacturingTime { private get; set; }
public SystemTime SystemTime { private get; set; }
public byte RebootCount { private get; set; }
public BuildInfo BuildInfo { private get; set; }
}
}
+21
View File
@@ -0,0 +1,21 @@
namespace OmniPlus.Features
{
public class FactorySeal : FeatureRequest
{
const int LENGTH = 1;
public FactorySeal() : base(LENGTH)
{
}
public FactorySeal(byte[] response) : base(response, LENGTH)
{
}
public bool Sealed
{
get => this.bytes[0] == 1;
set => this.bytes[0] = (byte)(value ? 1 : 0);
}
}
}
+35
View File
@@ -1,5 +1,8 @@
namespace OmniPlus.Features
{
using System.Collections.Generic;
using System.Security.Cryptography;
internal class Features
{
/// <summary>
@@ -248,6 +251,11 @@
/// </summary>
public const byte SET_BUILD_INFORMATION = 0x18;
public const byte VIEW_ALARM_SETTINGS = 0x1F;
public const byte SET_ALARM_SETTINGS = 0x20;
public const byte VIEW_ALARMS_STATE = 0x21;
public const byte CLEAR_ALARMS = 0x22;
public const byte DEVICE_SPECIFIC = 0xFD;
/// <summary>
@@ -266,6 +274,7 @@
/// with all of the response elements up to View Device ID String but no including the View ID String.
/// </summary>
public const byte VIEW_CONFIGURATION_PARAMETERS = 0xC7;
public const byte SET_CONFIGURATION_PARAMETERS = 0xC8;
/// <summary>
/// View volume per pulse.
@@ -334,5 +343,31 @@
/// Command is used to modify majority of the Factory Settings at one time to speed up Factory initialization time.
/// </summary>
public const byte SET_REGISTER_SETTINGS = 0x25;
/// <summary>
/// <para>0x00 means factory seal has not been set.</para>
/// <para>0x01 means factory seal has been set.</para>
/// </summary>
public const byte VIEW_FACTORY_SEAL = 0x63;
/// <summary>
///
/// </summary>
public const byte SET_FACTORY_SEAL = 0x64;
/// <summary>
/// Command is a Generic command used by the Factory to test,
/// calibrate or configure portions of the system that are not part of the normal operation of the meter.
/// <para>01 - Verify NFC Connectivity</para>
/// <para>02 - Enable NFC Periodic Updates and Initialize NFC Storage Memory</para>
/// <para>03 - Disable NFC Periodic Updates</para>
/// <para>04 - Force Update NFC NDEF data</para>
/// <para>05 - Force Update NFC Periodic RMA data</para>
/// <para>06 - View Sensor Setting</para>
/// <para>07 - Set Sensor Settings</para>
/// <para>0A - Board Variant and PcbId</para>
/// <para>0B - NFC Status</para>
/// </summary>
public const byte METROLOGY_TEST = 0x65;
}
}
@@ -1,6 +1,13 @@
namespace OmniPlus.Features
using System;
namespace OmniPlus.Features
{
public class ManifacturingTime : Epoch20000101
{
public static implicit operator ManifacturingTime(DateTime dateTime)
=> new ManifacturingTime
{
DateTime = dateTime,
};
}
}
@@ -1,7 +1,5 @@
namespace OmniPlus.Features
{
using System.Text;
public class ProgrammableID : ASCIIString
{
const int LENGTH = 20;
+16 -2
View File
@@ -1,7 +1,5 @@
using System;
using static OmniPlus.OmniPlusExtensions;
namespace OmniPlus.Features
{
public class RegisterSettings : FeatureRequest
@@ -93,5 +91,21 @@ namespace OmniPlus.Features
get => this.bytes[12].GetUint8(3, 3);
set => OmniPlusExtensions.SetUint8(ref this.bytes[12], 3, 3, value);
}
public override bool Equals(object other)
=> other is RegisterSettings registerSettings
&& registerSettings.IntPart == this.IntPart
&& registerSettings.Fraction == this.Fraction
&& registerSettings.Size == this.Size
&& registerSettings.Range == this.Range
&& registerSettings.VolumePerPulseUnit == this.VolumePerPulseUnit
&& registerSettings.MeterUnits == this.MeterUnits
&& registerSettings.FlowUnits == this.FlowUnits
&& registerSettings.FlowRate == this.FlowRate
&& registerSettings.FactoryCorrection == this.FactoryCorrection
&& registerSettings.FieldCorrection == this.FieldCorrection
&& registerSettings.PulseWeight == this.PulseWeight
&& registerSettings.PulseWidth == this.PulseWidth
&& registerSettings.PulseUpdate == this.PulseUpdate;
}
}
+10 -2
View File
@@ -1,13 +1,21 @@
namespace OmniPlus.Features
using System;
namespace OmniPlus.Features
{
public class SystemTime : Epoch20000101
{
public SystemTime()
public SystemTime() : base()
{
}
public SystemTime(byte[] response) : base(response)
{
}
public static implicit operator SystemTime(DateTime dateTime)
=> new SystemTime
{
DateTime = dateTime,
};
}
}
+10 -1
View File
@@ -40,7 +40,6 @@
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
@@ -49,6 +48,9 @@
<Compile Include="Enums\ReadingSettings.cs" />
<Compile Include="Enums\Status.cs" />
<Compile Include="Enums\TimeUnits.cs" />
<Compile Include="Features\Alarm.cs" />
<Compile Include="Features\AlarmSettings.cs" />
<Compile Include="Features\AlarmsState.cs" />
<Compile Include="Features\ASCIIString.cs" />
<Compile Include="Features\BatteryVoltage.cs" />
<Compile Include="Features\BuildInfo.cs" />
@@ -59,6 +61,7 @@
<Compile Include="Features\DeviceID.cs" />
<Compile Include="Features\Epoch20000101.cs" />
<Compile Include="Features\FactoryID.cs" />
<Compile Include="Features\FactorySeal.cs" />
<Compile Include="Features\Features.cs" />
<Compile Include="Features\FeatureRequest.cs" />
<Compile Include="Features\FeatureResponse.cs" />
@@ -108,5 +111,11 @@
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SignalRClient\SignalRClient.csproj">
<Project>{5C16DAC4-71E5-49B4-A087-36C704AADCF1}</Project>
<Name>SignalRClient</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+198 -113
View File
@@ -3,7 +3,7 @@ using OmniPlus.Hanlers;
using static OmniPlus.Features.Features;
namespace OmniPlus.Connections
namespace OmniPlus
{
public class OmniPlusConnection
{
@@ -51,13 +51,6 @@ namespace OmniPlus.Connections
return new FactoryID(response);
}
public FeatureResponse SetFactoryID(FactoryID factoryID)
{
var response = this.MessageHandler.Invoke(factoryID[SET_FACTORY_ID]);
return new FeatureResponse(response);
}
public ProgrammableID ViewProgrammableID()
{
var response = this.MessageHandler.Invoke(VIEW_PROGRAMMABLE_ID);
@@ -65,13 +58,6 @@ namespace OmniPlus.Connections
return new ProgrammableID(response);
}
public FeatureResponse SetProgrammableID(ProgrammableID programmableID)
{
var response = this.MessageHandler.Invoke(programmableID[SET_PROGRAMMABLE_ID]);
return new FeatureResponse(response);
}
public VersionAndType ViewVersionAndType()
{
var response = this.MessageHandler.Invoke(VIEW_VERSION_AND_TYPE);
@@ -86,13 +72,6 @@ namespace OmniPlus.Connections
return new CustomerText(response);
}
public FeatureResponse SetCustomerText(CustomerText customerText)
{
var response = this.MessageHandler.Invoke(customerText[SET_CUSTOMER_TEXT]);
return new FeatureResponse(response);
}
public ReadingDigits ViewReadingDigits()
{
var response = this.MessageHandler.Invoke(VIEW_READING_DIGITS);
@@ -100,13 +79,6 @@ namespace OmniPlus.Connections
return new ReadingDigits(response);
}
public FeatureResponse SetReadingDigits(ReadingDigits readingDigits)
{
var response = this.MessageHandler.Invoke(readingDigits[SET_READING_DIGITS]);
return new FeatureResponse(response);
}
public ReadingUnits ViewReadingUnits()
{
var response = this.MessageHandler.Invoke(VIEW_READING_UNITS);
@@ -114,13 +86,6 @@ namespace OmniPlus.Connections
return new ReadingUnits(response);
}
public FeatureResponse SetReadingUnits(ReadingUnits readingUnits)
{
var response = this.MessageHandler.Invoke(readingUnits[SET_READING_UNITS]);
return new FeatureResponse(response);
}
public RateUnits ViewRateUnits()
{
var response = this.MessageHandler.Invoke(VIEW_RATE_UNITS);
@@ -128,13 +93,6 @@ namespace OmniPlus.Connections
return new RateUnits(response);
}
public FeatureResponse SetRateUnits(RateUnits rateUnits)
{
var response = this.MessageHandler.Invoke(rateUnits[SET_RATE_UNITS]);
return new FeatureResponse(response);
}
public ReadingResolution ViewReadingResolution()
{
var response = this.MessageHandler.Invoke(VIEW_READING_RESOLUTION);
@@ -142,20 +100,6 @@ namespace OmniPlus.Connections
return new ReadingResolution(response);
}
public FeatureResponse SetReadingResolution(ReadingResolution readingResolution)
{
var response = this.MessageHandler.Invoke(readingResolution[SET_READING_RESOLUTION]);
return new FeatureResponse(response);
}
public FeatureResponse SetManifacturingTime(ManifacturingTime manifacturingTime)
{
var response = this.MessageHandler.Invoke(manifacturingTime[DEVICE_SPECIFIC, SET_MANIFACTURING_TIME]);
return new FeatureResponse(response);
}
public RateResolution ViewRateResolution()
{
var response = this.MessageHandler.Invoke(VIEW_RATE_RESOLUTION);
@@ -163,13 +107,6 @@ namespace OmniPlus.Connections
return new RateResolution(response);
}
public FeatureResponse SetRateResolution(RateResolution rateResolution)
{
var response = this.MessageHandler.Invoke(rateResolution[SET_READING_RESOLUTION]);
return new FeatureResponse(response);
}
public Readings ViewReadings(Readings reading)
{
var response = this.MessageHandler.Invoke(VIEW_READINGS);
@@ -177,13 +114,6 @@ namespace OmniPlus.Connections
return new Readings(response);
}
public FeatureResponse SetReadingPreset(ReadingPreset readingPreset)
{
var response = this.MessageHandler.Invoke(readingPreset[SET_READING_PRESET]);
return new FeatureResponse(response);
}
public ReadingMode ViewReadingMode()
{
var response = this.MessageHandler.Invoke(VIEW_READING_MODE);
@@ -191,13 +121,6 @@ namespace OmniPlus.Connections
return new ReadingMode(response);
}
public FeatureResponse SetReadingMode(ReadingMode readingMode)
{
var response = this.MessageHandler.Invoke(readingMode[SET_READING_MODE]);
return new FeatureResponse(response);
}
public BuildInfo ViewBuildInformation()
{
var response = this.MessageHandler.Invoke(VIEW_BUILD_INFORMATION);
@@ -205,13 +128,6 @@ namespace OmniPlus.Connections
return new BuildInfo(response);
}
public FeatureResponse SetBuildInformation(BuildInfo buildInformation)
{
var response = this.MessageHandler.Invoke(buildInformation[SET_BUILD_INFORMATION]);
return new FeatureResponse(response);
}
public SystemParameters ViewSystemParameters()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_SYSTEM_PARAMETERS);
@@ -226,20 +142,13 @@ namespace OmniPlus.Connections
return new ConfigurationParameters(response);
}
public InputVolume SetInputVolume()
public InputVolume ViewInputVolume()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_INPUT_VOLUME);
return new InputVolume(response);
}
public FeatureResponse SetInputVolume(InputVolume inputVolume)
{
var response = this.MessageHandler.Invoke(inputVolume[DEVICE_SPECIFIC, SET_INPUT_VOLUME]);
return new FeatureResponse(response);
}
public ChamberCalibrationRequest StartChamberCalibration(ushort rotations, ushort duration)
{
var response = this.MessageHandler.Invoke(new ChamberCalibrationRequest
@@ -247,7 +156,7 @@ namespace OmniPlus.Connections
Rotations = rotations,
Duration = duration,
Control = ChamberCalibrationRequest.ACTIVATE_TEST
});
}[DEVICE_SPECIFIC, CHAMBER_CALIBRATION]);
return new ChamberCalibrationRequest(response);
}
@@ -259,14 +168,189 @@ namespace OmniPlus.Connections
return new ChamberCalibrationResponse(response);
}
internal SystemTime ViewSystemTime()
public SystemTime ViewSystemTime()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_SYSTEM_TIME);
return new SystemTime(response);
}
internal FeatureResponse SetSystemTime(SystemTime request = null)
public RegisterSettings ViewRegisterSettings()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_REGISTER_SETTINGS);
return new RegisterSettings(response);
}
public FeatureResponse ViewRegisterSettings(FeatureRequest request)
{
var response = this.MessageHandler.Invoke(request[DEVICE_SPECIFIC, SET_REGISTER_SETTINGS]);
return new RegisterSettings(response);
}
public AlarmsState ViewAlarmsState()
{
var response = this.MessageHandler.Invoke(VIEW_ALARMS_STATE, 0xFF, 0x00, 0x00);
return new AlarmsState(response);
}
public AlarmSettings ViewAlarmSettings(byte alarmID)
{
var response = this.MessageHandler.Invoke(VIEW_ALARM_SETTINGS, 0x00, alarmID, 0x01);
return new AlarmSettings(response);
}
public FactorySeal ViewFactorySeal()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_FACTORY_SEAL);
return new FactorySeal(response);
}
public FeatureResponse ClearAlarms()
{
var response = this.MessageHandler.Invoke(CLEAR_ALARMS, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
return new FeatureResponse(response);
}
public FeatureResponse ClearDisplay()
{
var response = this.MessageHandler.Invoke(SET_READING_UNITS, 0xFF);
return new FeatureResponse(response);
}
public FeatureResponse EnableNFC()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, METROLOGY_TEST, 0x02);
return new FeatureResponse(response);
}
public FeatureResponse Set(Alarm alarm)
{
var response = this.MessageHandler.Invoke(alarm[SET_ALARM_SETTINGS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(BuildInfo buildInformation)
{
var response = this.MessageHandler.Invoke(buildInformation[SET_BUILD_INFORMATION]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ConfigurationParameters configurationParameters)
{
var response = this.MessageHandler.Invoke(configurationParameters[DEVICE_SPECIFIC, SET_CONFIGURATION_PARAMETERS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(CustomerText customerText)
{
var response = this.MessageHandler.Invoke(customerText[SET_CUSTOMER_TEXT]);
return new FeatureResponse(response);
}
public FeatureResponse Set(FactoryID factoryID)
{
var response = this.MessageHandler.Invoke(factoryID[SET_FACTORY_ID]);
return new FeatureResponse(response);
}
public FeatureResponse Set(FactorySeal factorySeal)
{
var response = this.MessageHandler.Invoke(factorySeal[DEVICE_SPECIFIC, SET_FACTORY_SEAL]);
return new FeatureResponse(response);
}
public FeatureResponse Set(InputVolume inputVolume)
{
var response = this.MessageHandler.Invoke(inputVolume[DEVICE_SPECIFIC, SET_INPUT_VOLUME]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ManifacturingTime manifacturingTime)
{
var response = this.MessageHandler.Invoke(manifacturingTime[DEVICE_SPECIFIC, SET_MANIFACTURING_TIME]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ProgrammableID programmableID)
{
var response = this.MessageHandler.Invoke(programmableID[SET_PROGRAMMABLE_ID]);
return new FeatureResponse(response);
}
public FeatureResponse Set(RateUnits rateUnits)
{
var response = this.MessageHandler.Invoke(rateUnits[SET_RATE_UNITS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(RateResolution rateResolution)
{
var response = this.MessageHandler.Invoke(rateResolution[SET_READING_RESOLUTION]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ReadingDigits readingDigits)
{
var response = this.MessageHandler.Invoke(readingDigits[SET_READING_DIGITS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ReadingMode readingMode)
{
var response = this.MessageHandler.Invoke(readingMode[SET_READING_MODE]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ReadingPreset readingPreset)
{
var response = this.MessageHandler.Invoke(readingPreset[SET_READING_PRESET]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ReadingUnits readingUnits)
{
var response = this.MessageHandler.Invoke(readingUnits[SET_READING_UNITS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(ReadingResolution readingResolution)
{
var response = this.MessageHandler.Invoke(readingResolution[SET_READING_RESOLUTION]);
return new FeatureResponse(response);
}
public FeatureResponse Set(RegisterSettings request)
{
var response = this.MessageHandler.Invoke(request[DEVICE_SPECIFIC, SET_REGISTER_SETTINGS]);
return new FeatureResponse(response);
}
public FeatureResponse Set(SystemTime request = null)
{
if (request is null)
{
@@ -278,25 +362,26 @@ namespace OmniPlus.Connections
return new FeatureResponse(response);
}
internal RegisterSettings ViewRegisterSettings()
public FeatureResponse Unseal()
{
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_REGISTER_SETTINGS);
// TODO: Implement factory unseal.
// 1. ((View Seconds Active) >> 8) &0xFFFF
// 2. CRC16_iPERL(View Factory ID),
// 3. ViewCustomerText.Substring(0, 4).Sum(x => x.Count(x => x == 1))
// 4. ViewReadingPreset.Substring(3, 4)
// - The ASCII values in hex for those characters are 0x33 34 35 36 which when reinterpreted as a uint32BE represents
// - the value 859059510 in decimal. That, mod 11 is 1, so VVVV is 0x0001.
// - When the input data is a string, and does not contain the number of characters required for this algorithm,
// - the value used is the input data written over the value “Factory”.
// - For example, if View Customer Text returns the string “Boo”, the value used in the CCCC step would be “Bootory.”
// - Note that due to the reliance on time and reading, the hash may become invalidated before you are able
// - to send the unseal command.Because of this, if the register responds with Unable to execute,
// - you should recalculate the hash which should last for a longer period if SSSS is large / close to rolling over.
// - Also, if the 7th digit rolls over during unsealing, the hash will not be valid.
// - Current system time is written into manufacturing date/ time if the manufacturing date/ time has not been set
// - when factory seal is set.
return new RegisterSettings(response);
}
internal FeatureResponse ViewRegisterSettings(FeatureRequest request)
{
var response = this.MessageHandler.Invoke(request[DEVICE_SPECIFIC, SET_REGISTER_SETTINGS]);
return new RegisterSettings(response);
}
internal FeatureResponse SetRegisterSettings(RegisterSettings request)
{
var response = this.MessageHandler.Invoke(request[DEVICE_SPECIFIC, SET_REGISTER_SETTINGS]);
return new FeatureResponse(response);
return new FeatureResponse();
}
}
}
+153 -5
View File
@@ -1,4 +1,4 @@
using OmniPlus.Connections;
using OmniPlus;
using OmniPlus.Enums;
using OmniPlus.Features;
@@ -18,6 +18,8 @@ namespace OmniPlus
private readonly ConcurrentDictionary<int, OmniPlusConnection> connections;
private readonly ConcurrentDictionary<int, OmniPlusMeter> meters;
private readonly CancellationTokenSource cancellationTokenSource;
private readonly CancellationToken cancellationToken;
private readonly SignalRConnection signalRConnection;
private readonly OmniPlusDatabase database;
private readonly OmniPlusType omniType;
@@ -30,12 +32,15 @@ namespace OmniPlus
{
this.connections = new ConcurrentDictionary<int, OmniPlusConnection>();
this.meters = new ConcurrentDictionary<int, OmniPlusMeter>();
this.cancellationTokenSource = new CancellationTokenSource();
this.signalRConnection = new SignalRConnection(signalRURL);
this.database = new OmniPlusDatabase(dbConnectionString);
this.omniType = new OmniPlusType();
this.size = 5;
this.variant = "C2";
this.cancellationToken = this.cancellationTokenSource.Token;
this.cancellationToken.Register(this.CancellationCallback);
}
public void Dispose()
@@ -107,6 +112,9 @@ namespace OmniPlus
this.database.LoadOmniPlusType(this.size, this.variant, this.omniType);
}
public void CancelExecution()
=> this.cancellationTokenSource.Cancel(false);
public void StartInspection()
{
this.background = new BackgroundWorker();
@@ -180,7 +188,7 @@ namespace OmniPlus
this.database.AddOrUpdate(position, systemParameters);
}
meter.CanCalibrate = connection.SetInputVolume(this.omniType.InputVolume).Succeeded;
meter.CanCalibrate = connection.Set(this.omniType.InputVolume).Succeeded;
this.StateChanged?.Invoke(position, meter.FirmwareInRange ? 1 : -1, FIRMWARE, meter.Firmware);
this.StateChanged?.Invoke(position, !string.IsNullOrWhiteSpace(meter.BuildInfo) ? 1 : -1, BUILD_INFO, meter.BuildInfo);
@@ -251,7 +259,7 @@ namespace OmniPlus
{
var header = $"{point.VolumeM3H:0.0000}m³/h";
if (this.TryGetOmni(position, out var connection, out var meter) && meter.Initialized && meter.CanCalibrate)
if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
{
var difference = meter.AddCalibrationVolume(point, volume);
@@ -265,7 +273,7 @@ namespace OmniPlus
private void GetCorrectionFactor(int position)
{
if (this.TryGetOmni(position, out var connection, out var meter) && meter.Initialized && meter.CanCalibrate)
if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
{
var correctionFactor = meter.GetCorrectionFactor();
@@ -292,6 +300,7 @@ namespace OmniPlus
if (canContinue)
{
// TODO: Uncomment in production
//var systemTimeReset = connection.SetSystemTime();
//canContinue = systemTimeReset.Succeeded;
}
@@ -314,13 +323,146 @@ namespace OmniPlus
registerSettings.PulseWidth = 0x02;
registerSettings.PulseUpdate = 0x00;
var response = connection.SetRegisterSettings(registerSettings);
var response = connection.Set(registerSettings);
canContinue = response.Succeeded;
if (canContinue)
{
meter.AddRegisterSettings(registerSettings);
}
}
if (canContinue)
{
configurationParameters.ProgrammableID = meter.ProgrammableID;
configurationParameters.FactoryID = meter.FactoryID;
configurationParameters.ReadingDigits = meter.ReadingDigits;
configurationParameters.Readings = meter.Readings;
configurationParameters.OptionalUniDirFields = meter.OptionalUniDirFields;
configurationParameters.AlartPersistenceDays = meter.AlartPersistenceDays;
configurationParameters.DataLogIntervalMins = meter.DataLogIntervalMins;
configurationParameters.ManifacturingTime = meter.ManifacturingTime;
configurationParameters.SystemTime = DateTime.UtcNow;
configurationParameters.RebootCount = 0;
configurationParameters.BuildInfo = meter.BuildInfo;
configurationParameters.DeviceID = meter.DeviceID;
var response = connection.Set(configurationParameters);
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.ClearDisplay();
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.Set(new LeakAlarm
{
FlowRateGal = 0.25F, // 0.25 gpm
TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
});
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.Set(new HighFlowAlarm
{
FlowRateGal = 25F, // 25 gpm
TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
});
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.Set(new ReverseFlowAlarm
{
FlowRateGal = -1F, // -1 gpm
TimeLimit = 60 // 1 hours => 86400sec
});
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.ClearAlarms();
canContinue = response.Succeeded;
}
if (canContinue)
{
var alarmsState = connection.ViewAlarmsState();
canContinue = alarmsState.Succeeded
&& alarmsState.UsrEnabled
&& alarmsState.PreEnabledInactive;
}
if (canContinue)
{
var response = connection.EnableNFC();
canContinue = response.Succeeded;
}
if (canContinue)
{
var registerSettingsAfter = connection.ViewRegisterSettings();
canContinue = registerSettingsAfter.Succeeded
&& meter.Compare(registerSettingsAfter);
}
if (canContinue)
{
var systemParametersAfter = connection.ViewSystemParameters();
canContinue = systemParametersAfter.Succeeded
&& meter.Compare(systemParametersAfter);
}
if (canContinue)
{
var configurationParametersAfter = connection.ViewConfigurationParameters();
canContinue = configurationParametersAfter.Succeeded
&& meter.Compare(configurationParametersAfter);
}
if (canContinue)
{
var alarmsState = connection.ViewAlarmsState();
canContinue = alarmsState.Succeeded
&& alarmsState.UsrEnabled
&& alarmsState.PreEnabledInactive;
}
if (canContinue)
{
var response = connection.ViewAlarmSettings(0x01);
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.ViewAlarmSettings(0x02);
canContinue = response.Succeeded;
}
if (canContinue)
{
var response = connection.ViewAlarmSettings(0x04);
canContinue = response.Succeeded;
}
if (canContinue)
{
//connection.Set(new FactorySeal
//{
// Sealed = true,
//});
//var factorySeal = connection.ViewFactorySeal();
//canContinue = factorySeal.Succeeded && factorySeal.Sealed;
}
}
else // meter or connection not in use
@@ -367,5 +509,11 @@ namespace OmniPlus
timer.Stop();
}
private void CancellationCallback()
{
// TODO: Update database.
this.Dispose();
}
}
}
+41
View File
@@ -345,6 +345,23 @@ namespace OmniPlus
return bits;
}
public static byte[] GetBits(this byte[] bytes)
{
var bytesL = bytes.Length;
var bitsL = bytesL * BYTE_BITS;
var bits = new byte[bitsL];
for (int i = 0; i < bytesL; i++)
{
for (int b = 0; b < BYTE_BITS; b++)
{
bits[i + b] = (byte)(bytes[i] >> b & 1);
}
}
return bytes;
}
public static byte ToUint8(this byte[] bits)
{
var sum = default(byte);
@@ -376,5 +393,29 @@ namespace OmniPlus
x = dst.ToUint8();
}
public static byte[] Subarray(this byte[] bytes, int start, int length)
{
var subarray = new byte[length];
Array.Copy(bytes, start, subarray, 0, length);
return subarray;
}
public static byte[] Reverse(this byte[] bytes)
{
var length = bytes.Length / 2;
for (int i = 0; i < length; i++)
{
var last = length - i - 1;
var first = bytes[i];
bytes[i] = bytes[last];
bytes[last] = first;
}
return bytes;
}
}
}
+40 -4
View File
@@ -11,6 +11,8 @@ namespace OmniPlus
private readonly IDictionary<OmniPlusTestPoint, OmniPlusTest> testPoints;
private SystemParameters systemParameters;
private ConfigurationParameters configurationParameters;
private RegisterSettings registerSettings;
public OmniPlusMeter(bool connected = false)
{
@@ -92,6 +94,30 @@ namespace OmniPlus
set => this.systemParameters.FactorySealed = value;
}
public ProgrammableID ProgrammableID
=> this.configurationParameters.ProgrammableID;
public FactoryID FactoryID
=> this.configurationParameters.FactoryID;
public ReadingDigits ReadingDigits
=> this.configurationParameters.ReadingDigits;
public Readings Readings
=> this.configurationParameters.Readings;
public OptionalUniDirFields OptionalUniDirFields
=> this.configurationParameters.OptionalUniDirFields;
public byte AlartPersistenceDays
=> this.configurationParameters.AlartPersistenceDays;
public ushort DataLogIntervalMins
=> this.configurationParameters.DataLogIntervalMins;
public DeviceID DeviceID
=> this.configurationParameters.DeviceID;
internal double AddCalibrationResult(OmniPlusTestPoint point, ChamberCalibrationResponse result)
{
this.testPoints[point] = new OmniPlusTest
@@ -111,10 +137,11 @@ namespace OmniPlus
return this.testPoints[point].DifferencePercentage;
}
internal void AddConfigurationParameters(ConfigurationParameters configurationParameters)
{
// TODO: throw new NotImplementedException();
}
internal void AddConfigurationParameters(ConfigurationParameters configurationParameters)
=> this.configurationParameters = configurationParameters;
internal void AddRegisterSettings(RegisterSettings registerSettings)
=> this.registerSettings = registerSettings;
internal void AddSystemParameters(SystemParameters systemParameters)
{
@@ -138,6 +165,15 @@ namespace OmniPlus
}
}
internal bool Compare(RegisterSettings registerSettingsAfter)
=> registerSettingsAfter.Equals(registerSettings);
internal bool Compare(SystemParameters systemParametersAfter)
=> systemParametersAfter.Equals(this.systemParameters);
internal bool Compare(ConfigurationParameters configurationParametersAfter)
=> configurationParametersAfter.Equals(this.configurationParameters);
internal double GetCorrectionFactor()
{
this.CorrectionFactor = this.testPoints
+1 -1
View File
@@ -24,7 +24,7 @@
void WaitUntilReached(double _) => reached = true;
this.exchangeHub.ExchangeQ += WaitUntilReached;
this.exchangeHub.SetQ(value);
this.exchangeHub.SendExchangeQ(value);
while (!reached && seconds >= 0)
{
+1 -1
View File
@@ -12,4 +12,4 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /></startup></configuration>