Files
laatzen/Common/Hardware/WaterMeter/MagFlux/MagFluxCore/MagFluxMeter.cs
T

544 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}
}