restructured WaterMeter
This commit is contained in:
@@ -0,0 +1,543 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.SerialPorts;
|
||||
using Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol;
|
||||
using Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig;
|
||||
using Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.RequestProtocol;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
using Xylem.Common.Metrology.Measurements.Consts;
|
||||
using Xylem.Common.Utils.Logging;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxCore
|
||||
{
|
||||
/// <inheritdoc cref="IMeter" />
|
||||
/// <summary>
|
||||
/// MagFlux meter is the core class for the MJK MagFlux water meter.
|
||||
/// One meter always is always linked to two port, one for communication and one for LED streaming.
|
||||
/// </summary>
|
||||
public class MagFluxMeter : IMeter, IMeterEvents
|
||||
{
|
||||
#region class handling
|
||||
|
||||
/// <summary>
|
||||
/// Ctor - default
|
||||
/// </summary>
|
||||
/// <remarks date="2023-Apr-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public MagFluxMeter()
|
||||
{
|
||||
SetLogger();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
/// <param name="slot">Slot number for test-bench </param>
|
||||
/// <param name="requestPort"><see cref="PortConfig" /> for request Port</param>
|
||||
/// <param name="streamingPort"><see cref="PortConfig" /> for streaming Port</param>
|
||||
/// <param name="ignoreCorruptedData">don´t send CRC error or telegrams with error flag to caller</param>
|
||||
/// <param name="password">
|
||||
/// If you have a password for highest access level you need, if you don't want to access the meter
|
||||
/// (just read led record) than you can leave it null
|
||||
/// </param>
|
||||
/// <remarks date="2023-Apr-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public MagFluxMeter(Int32 slot, PortConfig? requestPort, PortConfig? streamingPort,
|
||||
Boolean ignoreCorruptedData = true, String password = null)
|
||||
{
|
||||
_logger = NLogHelper.CreateOrGetMultiLogger($"Slot:{slot}", "Slot", "Meter", "MeterBase", "MeterBase");
|
||||
SetupMagFluxMeter(slot, requestPort, streamingPort, ignoreCorruptedData, password);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region variables and properties
|
||||
|
||||
/// <summary>
|
||||
/// Represent pcb serial number
|
||||
/// </summary>
|
||||
public String PcbId
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private String _currentActionText = "";
|
||||
/// <summary>
|
||||
/// Hold the current process name e.g. FlowTest, Preadjustemtn for logging
|
||||
/// </summary>
|
||||
public String CurrentActionText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentActionText;
|
||||
}
|
||||
set
|
||||
{
|
||||
_currentActionText = value;
|
||||
SetLogger();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add on ctor a password and it will be used for login in if no other password is set
|
||||
/// </summary>
|
||||
private String _password;
|
||||
|
||||
/// <summary>
|
||||
/// request port assignment/info
|
||||
/// </summary>
|
||||
public IPort RequestPort
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// request protocol assignment/info
|
||||
/// </summary>
|
||||
public RequestProtocol RequestProtocol;
|
||||
|
||||
/// <summary>
|
||||
/// streaming port assignment/info
|
||||
/// </summary>
|
||||
public IPort StreamingPort
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// streaming protocol assignment/info
|
||||
/// </summary>
|
||||
public StreamingProtocol StreamingProtocol;
|
||||
|
||||
/// <inheritdoc />
|
||||
public String SerialNumber
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ProcessState ProcessStatus
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ErrorState ErrorStatus
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Int32 Slot
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Int32 IntermediateUpdateTimeS
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Process configuration
|
||||
/// </summary>
|
||||
public ProcessConfig Configuration = new ProcessConfig();
|
||||
|
||||
/// <summary>
|
||||
/// Transmit protocol access for underlie objects to change response timeout
|
||||
/// </summary>
|
||||
public ITransmitProtocol TransmitProtocol;
|
||||
|
||||
//initially do not signal event
|
||||
private readonly AutoResetEvent _onSyncKeepSessionThread = new AutoResetEvent(false);
|
||||
private Thread _keepSessionThread;
|
||||
private Timer _keepSessionTimer;
|
||||
private readonly CancellationTokenSource _keepSessionToken = new CancellationTokenSource();
|
||||
|
||||
private ILogger _logger;
|
||||
private ILogger _loggerRawData;
|
||||
|
||||
#endregion
|
||||
|
||||
#region events
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnProcessStatusChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnErrorStatusChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnMeasurementInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnMeasurementCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnCalibInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnCalibCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeterEvents.OnProcessStatusChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnErrorStatusChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnMeasurementInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnMeasurementCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnCalibInitCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
event EventHandler IMeter.OnCalibCompleted
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler OnDisposeCompleted;
|
||||
#endregion
|
||||
|
||||
#region MagFlux handling
|
||||
/// <summary>
|
||||
/// just internal setup. called on ctor or from vb6 setup function
|
||||
/// </summary>
|
||||
/// <param name="slot">Slot Number for test-bench </param>
|
||||
/// <param name="requestPort"><see cref="PortConfig" /> for RFID/UART/IrDA Port</param>
|
||||
/// <param name="streamingPort"><see cref="PortConfig" /> for LED Port</param>
|
||||
/// <param name="ignoreCorruptedData">don´t send CRC error or telegrams with error flag to caller</param>
|
||||
/// <param name="password">
|
||||
/// If you have a password for highest access level you need, if you don't want to access the meter
|
||||
/// (just read led record) than you can leave it nullS
|
||||
/// </param>
|
||||
public void SetupMagFluxMeter(Int32 slot, PortConfig? requestPort, PortConfig? streamingPort,
|
||||
Boolean ignoreCorruptedData = true, String password = "")
|
||||
{
|
||||
Slot = slot;
|
||||
SetLogger();
|
||||
_password = password;
|
||||
|
||||
if (requestPort != null)
|
||||
{
|
||||
String requestIdent;
|
||||
if (requestPort.Value.Type == "Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.UartSerialPort")
|
||||
{
|
||||
requestIdent = $"Slot:{Slot}, Port:{requestPort.Value.PortName}, Protocol:Request, Type:UART -";
|
||||
|
||||
//CRC calculation does include the CRC itself filled with 0x0000 in advance
|
||||
RequestProtocol = new RequestProtocol(requestIdent);
|
||||
TransmitProtocol = new UartTransmitProtocol(requestPort.Value.PortName);
|
||||
RequestProtocol.SetTransmitProtocol(TransmitProtocol);
|
||||
|
||||
RequestPort = new UartSerialPort(requestIdent, requestPort.Value.GetSerialPort(),
|
||||
TransmitProtocol.GetTransmitPortSettings());
|
||||
}
|
||||
}
|
||||
|
||||
if (streamingPort != null)
|
||||
{
|
||||
var ledTransmit = new LedTransmitProtocol(streamingPort.Value.PortName);
|
||||
|
||||
var streamingIdent = $"Slot:{Slot}/{streamingPort.Value.PortName}-Protocol:LED";
|
||||
|
||||
StreamingPort = new LedSerialPort(streamingIdent, streamingPort.Value.GetSerialPort(),
|
||||
ledTransmit.GetTransmitPortSettings());
|
||||
StreamingProtocol = new StreamingProtocol(streamingIdent, ignoreCorruptedData);
|
||||
}
|
||||
Configuration = new ProcessConfig(ProgramConfig.ConfigFileName);
|
||||
_logger.Debug($"Slot:{Slot} - Setup done");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region logging
|
||||
private void SetLogger()
|
||||
{
|
||||
if (_logger != null)
|
||||
{
|
||||
LogManager.Flush();
|
||||
}
|
||||
if (string.IsNullOrEmpty(CurrentActionText))
|
||||
{
|
||||
_logger = NLogHelper.CreateOrGetMultiLogger($"Slot:{Slot}", $"", "Meter", "MeterBase", "MeterBase");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var id = !string.IsNullOrEmpty(SerialNumber) ? $"SN{SerialNumber}" : $"PCB{PcbId}";
|
||||
|
||||
_logger = NLogHelper.CreateOrGetMultiLogger($"Slot:{Slot}_{id}_{CurrentActionText}", $"Slot", "Meter", "MeterBase", "MeterBase");
|
||||
if (StreamingPort != null && StreamingPort is LedSerialPort)
|
||||
{
|
||||
var streamingIdent = $"LedRawData_Slot_{Slot}_{id}_{CurrentActionText}";
|
||||
|
||||
((LedSerialPort)StreamingPort).Ident = streamingIdent;
|
||||
((LedSerialPort)StreamingPort).RefreshLogger();
|
||||
|
||||
|
||||
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", "");
|
||||
var lastChat = pathMain.LastIndexOf('\\');
|
||||
pathMain = pathMain.Substring(lastChat + 1);
|
||||
pathRaw = Path.GetFileName(pathRaw);
|
||||
|
||||
var tmpUrl = $"http://10.49.40.25/MeterProcessState/api/TestBench/SetMeterLogPathInfo?SerialNumber={SerialNumber}&TestRunId={testRunString}&BasePath={basePath}&MainLogName={pathMain}&LEDName={pathRaw}";
|
||||
_logger.Debug($"Request Url: { tmpUrl}");
|
||||
//ToDO: Update to service URl
|
||||
LocalWebRequest.GetRequest(tmpUrl);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
/// <inheritdoc />
|
||||
public void ConnectMeter()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetupFromConfigFile(Int32 slot, Boolean ignoreCorruptedData = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean Logout()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean Login()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean Login(String password, Boolean runImmediately = true, Boolean skipReadMeterFwAndAssignRegisters = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void InitMeasurement()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StartMeasurement()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StopMeasurement()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeasurementResults GetMainMeasurementResult(Double? refVolume, Double? refTimeS,
|
||||
Boolean intermediateMeasurement = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<MeasurementResults> GetAllMeasurementResults(Double? refVolume, Double? refTimeS, Boolean intermediateMeasurement = false,
|
||||
Int32? channel = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeasurementStates GetMeasurementState(Int32? onlyChannelNr = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean RequestIntermediateMeasurementState(Int32? onlyChannelNr = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void InitCalibration()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StartCalibration()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void StopCalibration()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MeasurementStates GetCalibrationState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void BuildAndCheckCalibFactorsAllChannels(Double refVolumeCm, Double? refTimeS = null, Double reqDeviationPercent = 0,
|
||||
Double maxCalibFactorTolerancePercent = 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetCalibFactorsAllChannels(Boolean justLog = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetLcdText(Boolean release, Byte[] textInHex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetProcessState(DisplayCodes newState, Boolean webRequest = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DisplayCodes GetLastProcessState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WriteLog(String text)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void LogRawData(Boolean on)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Boolean CheckStateAfterMeasurement()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DisposeMeter()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user