tbf/TBF/Rig/Output/DB/ResultsWriter/ResultsWriter.cs

281 lines
7.7 KiB
C#

///
/// Copyright (c) 2026 Sensus Slovensko a.s.
///
using Common;
using log4net;
using Results.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using TBF.Rig.Generic;
using TBF.Rig.Output.DataStorage.UniDataStorageWriter;
using TBF.Rig.Output.DataStorage.UniDataStorageWriter.Interfaces;
using TBF.Rig.Sequences;
namespace TBF.Rig.Output.DB.ResultsWriter
{
public class ResultsWriter : ComponentBase, IOperation, GenericDevices.IResultsWriter, Generic.IDevice
{
private static readonly ILog log = LogManager.GetLogger(typeof(ResultsWriter));
public override string ToString()
{
return string.Format("{0}({1})", ClassName, Cfg.ToString(-1));
}
ResultsWriterCfg resultsWriterCfg;
Batch batch;
bool opCompleted;
bool anyError;
enum OpState
{
None,
WriteResultsScheduled,
WriteResultsRunning,
}
OpState currentOpState;
TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer dataStorageWriter;
public ResultsWriter()
{
}
public ResultsWriter(IComponentCfg cfg, IList<IComponent> components) : base(cfg)
{
resultsWriterCfg = cfg as ResultsWriterCfg;
if (resultsWriterCfg == null)
throw new ArgumentException("resultsWriterCfg");
currentOpState = OpState.None;
log.Warn(this.ToString());
IComponent parent =
components.FirstOrDefault(c => c.Name == resultsWriterCfg.ParentName);
if (parent == null)
{
throw new Exception(
string.Format("Parent '{0}' was not found.",
resultsWriterCfg.ParentName));
}
log.WarnFormat(
"ResultsWriter parent found: Name={0}, Type={1}",
parent.Name,
parent.GetType().FullName);
dataStorageWriter = parent as TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
if (dataStorageWriter == null)
{
throw new Exception(
string.Format(
"Parent '{0}' of type '{1}' is not UniDataStorageWriter.Writer.",
resultsWriterCfg.ParentName,
parent.GetType().FullName));
}
}
public ResultsWriter(IComponentCfg cfg) : base(cfg)
{
resultsWriterCfg = cfg as ResultsWriterCfg;
if (resultsWriterCfg == null)
throw new ArgumentException("resultsWriterCfg");
currentOpState = OpState.None;
log.Warn(this.ToString());
}
///
/// IDevice interface implementation
///
public override void Initialize()
{
}
public void RunDeviceBefore()
{
}
public void RunDeviceAfter()
{
}
public void StopDevice()
{
}
public void StopDevice2()
{
}
///
/// GenericDevices.IResultsWriter
///
public IOperation ProcessResultsOp(Batch batch)
{
if (!resultsWriterCfg.Enabled)
{
return null;
}
if (currentOpState == OpState.WriteResultsRunning)
{
throw new Exception("Sequence error");
}
this.batch = batch;
currentOpState = OpState.WriteResultsScheduled;
return this;
}
///
/// IOperation
///
public void Start()
{
if (currentOpState == OpState.WriteResultsScheduled)
{
currentOpState = OpState.WriteResultsRunning;
}
opCompleted = false;
anyError = false;
}
public Event Run()
{
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
if (currentOpState == OpState.WriteResultsRunning)
{
if (resultsWriterCfg.DebugLevel == DebugMode.Simulate)
{
return Event.ResultsWritten;
}
if (batch == null || batch.WaterMeters == null || batch.WaterMeters.Count == 0)
{
return Event.ResultsWritten;
}
if (opCompleted)
{
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
}
opCompleted = true;
try
{
WriteBatchResults(batch);
}
catch (Exception exc)
{
anyError = true;
log.ErrorFormat("Failed to write results by ResultsWriter: {0}", exc);
}
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
}
return Event.None;
}
public void Stop()
{
currentOpState = OpState.None;
}
public void WriteBatchResults(Batch batch)
{
resultsWriterCfg.UpdateRuntimeModel();
foreach (var wm in batch.WaterMeters)
{
if (wm == null || wm.Disabled)
continue;
DataWriteRequest request = BuildWriteRequest(wm);
if (request.InsertItems.Count == 0)
{
log.WarnFormat("No values to write for WM position {0}", wm.WMPosition);
continue;
}
log.InfoFormat("Writing WMPosition={0}, SerialNr={1}", wm.WMPosition, wm.SerialNr);
var result = dataStorageWriter.SetData(request);
if (!result.Success)
{
throw new Exception(result.Message);
}
log.WarnFormat(
"ResultsWriter wrote {0} value(s) for WM position {1}",
request.InsertItems.Count,
wm.WMPosition);
}
}
DataWriteRequest BuildWriteRequest(WaterMeter wm)
{
var request = new DataWriteRequest();
request.Mode = WriteMode.Insert;
if (resultsWriterCfg.SelectedItems == null)
return request;
foreach (var item in resultsWriterCfg.SelectedItems)
{
if (item == null)
continue;
string columnName = item.Caption;
if (string.IsNullOrWhiteSpace(columnName))
{
log.WarnFormat("Result item with empty Caption skipped: {0}", item);
continue;
}
request.InsertItems.Add(new InsertWriteItem()
{
ColumnName = columnName,
Value = item.Print(wm)
});
}
return request;
}
public void InitializeParent()
{
IComponent parent = TbfComponents.FindComponent(resultsWriterCfg.ParentName);
if (parent == null)
throw new Exception(
string.Format("Parent '{0}' was not found.", resultsWriterCfg.ParentName));
dataStorageWriter =
parent as TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
if (dataStorageWriter == null)
throw new Exception(
string.Format(
"Parent '{0}' of type '{1}' is not UniDataStorageWriter.Writer.",
resultsWriterCfg.ParentName,
parent.GetType().FullName));
}
}
}