Skip to content

Commit

Permalink
Merge pull request #1 from lzaslav/develop
Browse files Browse the repository at this point in the history
Additions to performance PR
  • Loading branch information
adv12 authored Nov 27, 2024
2 parents 6efab90 + e3255ad commit edd679e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 105 deletions.
74 changes: 52 additions & 22 deletions ISOv4Plugin/Mappers/LoggedDataMappers/Import/SectionMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using AgGateway.ADAPT.ApplicationDataModel.Equipment;
using AgGateway.ADAPT.ApplicationDataModel.LoggedData;
using AgGateway.ADAPT.ISOv4Plugin.ExtensionMethods;
using AgGateway.ADAPT.ISOv4Plugin.ISOModels;
using AgGateway.ADAPT.ISOv4Plugin.ObjectModel;

Expand Down Expand Up @@ -30,17 +31,50 @@ public List<DeviceElementUse> Map(ISOTime time,
IEnumerable<string> isoDeviceElementIDs,
Dictionary<string, List<ISOProductAllocation>> isoProductAllocations)
{
var usedDataLogValues = new List<ISODataLogValue>();

foreach (string isoDeviceElementID in isoDeviceElementIDs)
{
DeviceHierarchyElement hierarchyElement = TaskDataMapper.DeviceElementHierarchies.GetMatchingElement(isoDeviceElementID);
int? adaptDeviceElementId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElementID);
if (hierarchyElement != null &&
adaptDeviceElementId.HasValue &&
DataModel.Catalog.DeviceElements.Any(d => d.Id.ReferenceId == adaptDeviceElementId.Value))
{
usedDataLogValues.AddRange(_workingDataMapper.GetDataLogValuesForDeviceElement(time, hierarchyElement));
}
}

List<ISOSpatialRow> isoRecordsWithData = new List<ISOSpatialRow>();
if (usedDataLogValues.Any())
{
foreach (var isoRecord in isoRecords)
{
int beforeCount = usedDataLogValues.Count;
var notReferencedDataLogValues = usedDataLogValues.Where(x =>
!isoRecord.SpatialValues.Any(y => y.DataLogValue.ProcessDataIntDDI == x.ProcessDataIntDDI &&
y.DataLogValue.DeviceElementIdRef.ReverseEquals(x.DeviceElementIdRef)));
usedDataLogValues = notReferencedDataLogValues.ToList();
if (beforeCount != usedDataLogValues.Count)
{
isoRecordsWithData.Add(isoRecord);
}
if (usedDataLogValues.Count == 0)
{
break;
}
}
}


var sections = new List<DeviceElementUse>();
foreach (string isoDeviceElementID in isoDeviceElementIDs)
{
DeviceHierarchyElement hierarchyElement = TaskDataMapper.DeviceElementHierarchies.GetMatchingElement(isoDeviceElementID);
if (hierarchyElement != null)
{
DeviceElementUse deviceElementUse = null;
List<WorkingData> workingDatas = new List<WorkingData>();

//Get the relevant DeviceElementConfiguration
int adaptDeviceElementId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElementID).Value;
int? adaptDeviceElementId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElementID);
DeviceElement adaptDeviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == adaptDeviceElementId);
if (adaptDeviceElement != null)
{
Expand All @@ -55,33 +89,29 @@ public List<DeviceElementUse> Map(ISOTime time,
order = hierarchyElement.Parent.Order;
}

deviceElementUse = sections.FirstOrDefault(d => d.DeviceConfigurationId == config.Id.ReferenceId);
List<WorkingData> workingDatas = new List<WorkingData>();
DeviceElementUse deviceElementUse = sections.FirstOrDefault(d => d.DeviceConfigurationId == config.Id.ReferenceId);
if (deviceElementUse == null)
{
//Create the DeviceElementUse
deviceElementUse = new DeviceElementUse();
deviceElementUse.Depth = depth;
deviceElementUse.Order = order;
deviceElementUse.OperationDataId = operationDataId;
deviceElementUse.DeviceConfigurationId = config.Id.ReferenceId;

//Add Working Data for any data on this device element
List<WorkingData> data = _workingDataMapper.Map(time, isoRecords, deviceElementUse, hierarchyElement, sections, isoProductAllocations);
if (data.Any())
deviceElementUse = new DeviceElementUse
{
workingDatas.AddRange(data);
}
Depth = depth,
Order = order,
OperationDataId = operationDataId,
DeviceConfigurationId = config.Id.ReferenceId
};
}
else
{
workingDatas = deviceElementUse.GetWorkingDatas().ToList();
}

//Add Additional Working Data
List<WorkingData> data = _workingDataMapper.Map(time, isoRecords, deviceElementUse, hierarchyElement, sections, isoProductAllocations);
if (data.Any())
{
workingDatas.AddRange(data);
}
//Add Working Data for any data on this device element
List<WorkingData> data = _workingDataMapper.Map(time, isoRecordsWithData, deviceElementUse, hierarchyElement, sections, isoProductAllocations);
if (data.Any())
{
workingDatas.AddRange(data);
}

deviceElementUse.GetWorkingDatas = () => workingDatas;
Expand Down
36 changes: 10 additions & 26 deletions ISOv4Plugin/Mappers/LoggedDataMappers/Import/SpatialRecordMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,10 @@ public SpatialRecord Map(ISOSpatialRow isoSpatialRow, List<WorkingData> meters,
private void SetEnumeratedMeterValue(ISOSpatialRow isoSpatialRow, EnumeratedWorkingData meter, SpatialRecord spatialRecord)
{
var isoDataLogValue = _workingDataMapper.DataLogValuesByWorkingDataID[meter.Id.ReferenceId];
SpatialValue isoValue = null;
if (isoDataLogValue != null)
{
var tmp = isoSpatialRow.SpatialValuesById[isoDataLogValue.Index];
if (tmp != null)
{
ISODataLogValue dlv = tmp.DataLogValue;
if (dlv.DeviceElementIdRef.ReverseEquals(isoDataLogValue.DeviceElementIdRef))
{
isoValue = tmp;
}
}
}
var isoValue = isoSpatialRow.SpatialValues.FirstOrDefault(v =>
v.DataLogValue.ProcessDataIntDDI == isoDataLogValue.ProcessDataIntDDI &&
v.DataLogValue.DeviceElementIdRef.ReverseEquals(isoDataLogValue.DeviceElementIdRef)
);
if (isoValue != null)
{
var isoEnumeratedMeter = meter as ISOEnumeratedMeter;
Expand All @@ -123,19 +114,12 @@ private void SetNumericMeterValue(ISOSpatialRow isoSpatialRow, NumericWorkingDat
var dataLogValue = _workingDataMapper.DataLogValuesByWorkingDataID.ContainsKey(meter.Id.ReferenceId)
? _workingDataMapper.DataLogValuesByWorkingDataID[meter.Id.ReferenceId]
: null;
SpatialValue isoValue = null;
if (dataLogValue != null && dataLogValue.ProcessDataIntDDI != 0xDFFE)
{
var tmp = isoSpatialRow.SpatialValuesById[dataLogValue.Index];
if (tmp != null)
{
ISODataLogValue dlv = tmp.DataLogValue;
if (dlv.DeviceElementIdRef.ReverseEquals(dataLogValue.DeviceElementIdRef))
{
isoValue = tmp;
}
}
}
var isoValue = dataLogValue != null && dataLogValue.ProcessDataIntDDI != 0xDFEE
? isoSpatialRow.SpatialValues.FirstOrDefault(v =>
v.DataLogValue.ProcessDataIntDDI == dataLogValue.ProcessDataIntDDI &&
v.DataLogValue.DeviceElementIdRef.ReverseEquals(dataLogValue.DeviceElementIdRef)
)
: null;

if (isoValue != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public interface IWorkingDataMapper
WorkingData ConvertToBaseType(WorkingData meter);
Dictionary<int, ISODataLogValue> DataLogValuesByWorkingDataID { get; set; }
Dictionary<int, string> ISODeviceElementIDsByWorkingDataID { get; set; }

IEnumerable<ISODataLogValue> GetDataLogValuesForDeviceElement(ISOTime time, DeviceHierarchyElement deviceElementHierarchy);
}

public class WorkingDataMapper : BaseMapper, IWorkingDataMapper
Expand All @@ -40,6 +42,13 @@ public WorkingDataMapper(IEnumeratedMeterFactory enumeratedMeterCreatorFactory,
ISODeviceElementIDsByWorkingDataID = new Dictionary<int, string>();
}

public IEnumerable<ISODataLogValue> GetDataLogValuesForDeviceElement(ISOTime time, DeviceHierarchyElement deviceElementHierarchy)
{
return time.DataLogValues.Where(dlv => dlv.DeviceElementIdRef == deviceElementHierarchy.DeviceElement.DeviceElementId || //DLV DET reference matches the primary DET for the ADAPT element
deviceElementHierarchy.MergedElements.Any(e => e.DeviceElementId == dlv.DeviceElementIdRef)) //DLV DET reference matches one of the merged DETs on the ADAPT element
.ToList();
}

public List<WorkingData> Map(ISOTime time,
IEnumerable<ISOSpatialRow> isoSpatialRows,
DeviceElementUse deviceElementUse,
Expand Down
38 changes: 13 additions & 25 deletions ISOv4Plugin/Mappers/TimeLogMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,27 +340,9 @@ protected IEnumerable<OperationData> ImportTimeLog(ISOTask loggedTask, ISOTimeLo
ISOTime time = GetTimeElementFromTimeLog(isoTimeLog);

//Identify unique devices represented in this TimeLog data
List<string> deviceElementIDs = time.DataLogValues.Where(d => !d.ProcessDataDDI.EqualsIgnoreCase("DFFF") && !d.ProcessDataDDI.EqualsIgnoreCase("DFFE"))
List<string> deviceElementIDs = time.DataLogValues.Where(d => d.ProcessDataIntDDI != 0xDFFF && d.ProcessDataIntDDI != 0xDFFE)
.Select(d => d.DeviceElementIdRef).Distinct().ToList();

//Supplement the list with any parent device elements which although don't log data in the TLG
//May require a vrProductIndex working data based on product allocations
HashSet<string> parentsToAdd = new HashSet<string>();
foreach (string deviceElementID in deviceElementIDs)
{
ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(deviceElementID);
if (isoDeviceElement != null)
{
while (isoDeviceElement.Parent != null &&
isoDeviceElement.Parent is ISODeviceElement parentDet)
{
parentsToAdd.Add(parentDet.DeviceElementId);
isoDeviceElement= parentDet;
}
}
}
deviceElementIDs.AddRange(parentsToAdd);

Dictionary<ISODevice, HashSet<string>> loggedDeviceElementsByDevice = new Dictionary<ISODevice, HashSet<string>>();
foreach (string deviceElementID in deviceElementIDs)
{
Expand All @@ -373,6 +355,15 @@ protected IEnumerable<OperationData> ImportTimeLog(ISOTask loggedTask, ISOTimeLo
loggedDeviceElementsByDevice.Add(device, new HashSet<string>());
}
loggedDeviceElementsByDevice[device].Add(deviceElementID);

//Supplement the list with any parent device elements which although don't log data in the TLG
//May require a vrProductIndex working data based on product allocations
while (isoDeviceElement.Parent != null &&
isoDeviceElement.Parent is ISODeviceElement parentDet)
{
loggedDeviceElementsByDevice[device].Add(parentDet.DeviceElementId);
isoDeviceElement = parentDet;
}
}
}

Expand Down Expand Up @@ -890,7 +881,7 @@ public static IEnumerable<ISOSpatialRow> Read(string fileName, ISOTime templateT
//If the reported number of values does not fit into the stream, correct the numberOfDLVs
numberOfDLVs = ConfirmNumberOfDLVs(binaryReader, numberOfDLVs);

record.SpatialValuesById = new SpatialValue[templateTime.DataLogValues.Count];
record.SpatialValues = new List<SpatialValue>(numberOfDLVs);

bool unexpectedEndOfStream = false;
//Read DLVs out of the TLG.bin
Expand All @@ -908,10 +899,7 @@ public static IEnumerable<ISOSpatialRow> Read(string fileName, ISOTime templateT
SpatialValue spatialValue = CreateSpatialValue(templateTime, order, value, deviceHierarchies);
if (spatialValue != null)
{
if (record.SpatialValuesById[order] == null)
{
record.SpatialValuesById[order] = spatialValue;
}
record.SpatialValues.Add(spatialValue);
}
}
// Unable to read some of the expected DLVs, stop processing
Expand All @@ -924,7 +912,7 @@ public static IEnumerable<ISOSpatialRow> Read(string fileName, ISOTime templateT
foreach (ISODataLogValue fixedValue in templateTime.DataLogValues.Where(dlv => dlv.ProcessDataValue.HasValue && !EnumeratedMeterFactory.IsCondensedMeter(dlv.ProcessDataIntDDI)))
{
byte order = (byte)templateTime.DataLogValues.IndexOf(fixedValue);
SpatialValue matchingValue = record.SpatialValuesById[order];
SpatialValue matchingValue = record.SpatialValues.FirstOrDefault(s => s.Id == order);
if (matchingValue != null) //Check to ensure the binary data didn't already write this value
{
//Per the spec, any fixed value in the XML applies to all rows; as such, replace what was read from the binary
Expand Down
39 changes: 7 additions & 32 deletions ISOv4Plugin/ObjectModel/ISOSpatialRow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace AgGateway.ADAPT.ISOv4Plugin.ObjectModel
{
Expand All @@ -21,8 +20,7 @@ public class ISOSpatialRow
public uint? GpsUtcTime { get; set; }
public ushort? GpsUtcDate { get; set; }
public DateTime? GpsUtcDateTime { get; set; }
public IEnumerable<SpatialValue> SpatialValues => SpatialValuesById.Where(x => x != null);
public SpatialValue[] SpatialValuesById { get; set; }
public List<SpatialValue> SpatialValues { get; set; }

/// <summary>
/// Merge SpatialValues from provided SpatialRow into this one.
Expand All @@ -36,36 +34,13 @@ public ISOSpatialRow Merge(ISOSpatialRow otherRow)
return this;
}

SpatialValue[] mine = SpatialValuesById;
SpatialValue[] theirs = otherRow.SpatialValuesById;
if (theirs != null)
if (SpatialValues == null)
{
if (mine == null)
{
SpatialValuesById = theirs;
}
else
{
if (theirs.Length > mine.Length)
{
var tmp = mine;
mine = SpatialValuesById = theirs;
for (int i = 0; i < tmp.Length; i++)
{
mine[i] = tmp[i];
}
}
else
{
for (int i = 0; i < mine.Length && i < theirs.Length; i++)
{
if (mine[i] == null)
{
mine[i] = theirs[i];
}
}
}
}
SpatialValues = new List<SpatialValue>();
}
if (otherRow.SpatialValues != null)
{
SpatialValues.AddRange(otherRow.SpatialValues);
}

return this;
Expand Down

0 comments on commit edd679e

Please sign in to comment.