private IEnumerable <WorkingData> Map(ISODataLogValue dlv, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, int order, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { var workingDatas = new List <WorkingData>(); if (_ddis.ContainsKey(dlv.ProcessDataDDI.AsInt32DDI())) { NumericWorkingData numericMeter = MapNumericMeter(dlv, deviceElementUse.Id.ReferenceId, order); DataLogValuesByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv); workingDatas.Add(numericMeter); return(workingDatas); } var meterCreator = _enumeratedMeterCreatorFactory.GetMeterCreator(dlv.ProcessDataDDI.AsInt32DDI()); if (meterCreator != null) { var isoEnumeratedMeters = meterCreator.CreateMeters(isoSpatialRows); foreach (ISOEnumeratedMeter enumeratedMeter in isoEnumeratedMeters) { DataLogValuesByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv); enumeratedMeter.DeviceElementUseId = deviceElementUse.Id.ReferenceId; } workingDatas.AddRange(isoEnumeratedMeters); if (meterCreator is CondensedStateMeterCreator) { UpdateCondensedWorkingDatas(workingDatas, dlv, deviceElementUse, pendingDeviceElementUses, isoDeviceElementHierarchy); } } return(workingDatas); }
public List <DeviceElementUse> Map(ISOTime time, IEnumerable <ISOSpatialRow> isoRecords, int operationDataId, IEnumerable <string> isoDeviceElementIDs) { var sections = new List <DeviceElementUse>(); foreach (string isoDeviceElementID in isoDeviceElementIDs) { DeviceElementHierarchy hierarchy = TaskDataMapper.DeviceElementHierarchies.GetRelevantHierarchy(isoDeviceElementID); if (hierarchy != null) { DeviceElementUse deviceElementUse = null; List <WorkingData> workingDatas = new List <WorkingData>(); //Get the relevant DeviceElementConfiguration int adaptDeviceElementId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElementID).Value; DeviceElement adaptDeviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == adaptDeviceElementId); if (adaptDeviceElement != null) { DeviceElementConfiguration config = DeviceElementMapper.GetDeviceElementConfiguration(adaptDeviceElement, hierarchy, DataModel.Catalog); int depth = hierarchy.Depth; int order = hierarchy.Order; if (config.DeviceElementId == adaptDeviceElement.ParentDeviceId) { //The configuration references the parent ISO element depth = hierarchy.Parent.Depth; order = hierarchy.Parent.Order; } //Read any spatially-listed widths/offsets on this data onto the DeviceElementConfiguration objects hierarchy.SetWidthsAndOffsetsFromSpatialData(isoRecords, config, RepresentationMapper); //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, hierarchy, sections); if (data.Any()) { workingDatas.AddRange(data); } deviceElementUse.GetWorkingDatas = () => workingDatas; if (!sections.Contains(deviceElementUse)) { sections.Add(deviceElementUse); } } } } return(sections); }
private IEnumerable <WorkingData> Map(ISODataLogValue dlv, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, int order, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { var workingDatas = new List <WorkingData>(); if (_ddis.ContainsKey(dlv.ProcessDataDDI.AsInt32DDI())) { //Numeric Representations NumericWorkingData numericMeter = MapNumericMeter(dlv, deviceElementUse.Id.ReferenceId); DataLogValuesByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(numericMeter); return(workingDatas); } var meterCreator = _enumeratedMeterCreatorFactory.GetMeterCreator(dlv.ProcessDataDDI.AsInt32DDI()); if (meterCreator != null) { //Enumerated Representations var isoEnumeratedMeters = meterCreator.CreateMeters(isoSpatialRows); foreach (ISOEnumeratedMeter enumeratedMeter in isoEnumeratedMeters) { DataLogValuesByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv.DeviceElementIdRef); enumeratedMeter.DeviceElementUseId = deviceElementUse.Id.ReferenceId; } workingDatas.AddRange(isoEnumeratedMeters); if (meterCreator is CondensedStateMeterCreator) { UpdateCondensedWorkingDatas(workingDatas, dlv, deviceElementUse, pendingDeviceElementUses, isoDeviceElementHierarchy); } } else { //Proprietary DDIs - report out as numeric value NumericWorkingData proprietaryWorkingData = new NumericWorkingData(); proprietaryWorkingData.Representation = new ApplicationDataModel.Representations.NumericRepresentation { Code = dlv.ProcessDataDDI, CodeSource = RepresentationCodeSourceEnum.ISO11783_DDI }; proprietaryWorkingData.DeviceElementUseId = deviceElementUse.Id.ReferenceId; proprietaryWorkingData.UnitOfMeasure = AgGateway.ADAPT.Representation.UnitSystem.UnitSystemManager.GetUnitOfMeasure("count"); //Best we can do DataLogValuesByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(proprietaryWorkingData); } return(workingDatas); }
public List <WorkingData> Map(ISOTime time, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, DeviceElementHierarchy isoDeviceElementHierarchy, List <DeviceElementUse> pendingDeviceElementUses, Dictionary <string, List <ISOProductAllocation> > isoProductAllocations) { var workingDatas = new List <WorkingData>(); //Set orders on the collection of DLVs var allDLVs = time.DataLogValues; for (int order = 0; order < allDLVs.Count(); order++) { var dlv = allDLVs.ElementAt(order); dlv.Order = order; } //Create vrProductIndex on relevant device elements if more than one product on this OperationData if (TimeLogMapper.GetDistinctProductIDs(TaskDataMapper, isoProductAllocations).Count > 1 && isoProductAllocations.Keys.Contains(isoDeviceElementHierarchy.DeviceElement.DeviceElementId)) { WorkingData workingData = CreateProductIndexWorkingData(deviceElementUse.Id.ReferenceId); ISODeviceElementIDsByWorkingDataID.Add(workingData.Id.ReferenceId, isoDeviceElementHierarchy.DeviceElement.DeviceElementId); workingDatas.Add(workingData); } //Add the Working Datas for this DeviceElement IEnumerable <ISODataLogValue> deviceElementDLVs = allDLVs.Where(dlv => dlv.DeviceElementIdRef == isoDeviceElementHierarchy.DeviceElement.DeviceElementId); foreach (ISODataLogValue dlv in deviceElementDLVs) { IEnumerable <WorkingData> newWorkingDatas = Map(dlv, isoSpatialRows, deviceElementUse, dlv.Order, pendingDeviceElementUses, isoDeviceElementHierarchy); if (newWorkingDatas.Count() > 0) { int ddi = dlv.ProcessDataDDI.AsInt32DDI(); if (!EnumeratedMeterFactory.IsCondensedMeter(ddi)) { //We skip adding Condensed WorkingDatas to this DeviceElementUse since they were added separately below to their specific DeviceElementUse workingDatas.AddRange(newWorkingDatas); } } } return(workingDatas); }
private void UpdateCondensedWorkingDatas(List <WorkingData> condensedWorkingDatas, ISODataLogValue dlv, DeviceElementUse deviceElementUse, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(dlv.DeviceElementIdRef); IEnumerable <ISODeviceElement> isoSectionElements = isoDeviceElement.ChildDeviceElements.Where(d => d.DeviceElementType == ISOEnumerations.ISODeviceElementType.Section); if (isoSectionElements.Count() > 0 && isoSectionElements.Count() <= condensedWorkingDatas.Count) { //We have found the expected number of sections in the DDOP List <ISODeviceElement> targetSections = isoSectionElements.ToList(); //Update the DeviceElementReference on the Condensed WorkingDatas for (int i = 0; i < isoSectionElements.Count(); i++) { WorkingData workingData = condensedWorkingDatas[i]; DeviceElementUse condensedDeviceElementUse = new DeviceElementUse(); condensedDeviceElementUse.OperationDataId = deviceElementUse.OperationDataId; ISODeviceElement targetSection = targetSections[i]; int?deviceElementID = TaskDataMapper.InstanceIDMap.GetADAPTID(targetSection.DeviceElementId); if (deviceElementID.HasValue) { DeviceElement deviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == deviceElementID.Value); if (deviceElement != null) { //Reference the device element in its hierarchy so that we can get the depth & order DeviceElementHierarchy deviceElementInHierarchy = isoDeviceElementHierarchy.FromDeviceElementID(targetSection.DeviceElementId); //Get the config id DeviceElementConfiguration deviceElementConfig = DeviceElementMapper.GetDeviceElementConfiguration(deviceElement, deviceElementInHierarchy, DataModel.Catalog); condensedDeviceElementUse.DeviceConfigurationId = deviceElementConfig.Id.ReferenceId; //Set the depth & order condensedDeviceElementUse.Depth = deviceElementInHierarchy.Depth; condensedDeviceElementUse.Order = deviceElementInHierarchy.Order; } } condensedDeviceElementUse.GetWorkingDatas = () => new List <WorkingData> { workingData }; workingData.DeviceElementUseId = condensedDeviceElementUse.Id.ReferenceId; pendingDeviceElementUses.Add(condensedDeviceElementUse); } } }
public IEnumerable <DeviceElement> ImportDeviceElements(ISODevice isoDevice) { EnumeratedValue deviceClassification = DecodeMachineInfo(isoDevice.ClientNAME); ISODeviceElement rootDeviceElement = isoDevice.DeviceElements.SingleOrDefault(det => det.DeviceElementType == ISODeviceElementType.Device); if (rootDeviceElement == null) { //Short circuit on invalid TaskData TaskDataMapper.AddError("Missing root DeviceElement. Device will not be imported.", isoDevice.DeviceId.ToString(), "DeviceElementMapper"); return(null); } DeviceElementHierarchy rootDeviceElementHierarchy = TaskDataMapper.DeviceElementHierarchies.Items[isoDevice.DeviceId]; //Import device elements List <DeviceElement> adaptDeviceElements = new List <DeviceElement>(); //Import down the hierarchy to ensure integrity of parent references for (int i = 0; i <= rootDeviceElementHierarchy.GetMaxDepth(); i++) { IEnumerable <ISODeviceElement> isoDeviceElements = rootDeviceElementHierarchy.GetElementsAtDepth(i).Select(h => h.DeviceElement); foreach (ISODeviceElement isoDeviceElement in isoDeviceElements) { if (isoDeviceElement.DeviceElementType != ISODeviceElementType.Connector) { DeviceElement adaptDeviceElement = ImportDeviceElement(isoDeviceElement, deviceClassification, rootDeviceElementHierarchy); if (isoDeviceElement.DeviceElementType == ISODeviceElementType.Device) { //Setting the Device serial number on the root Device Element only adaptDeviceElement.SerialNumber = isoDevice.DeviceSerialNumber; } adaptDeviceElements.Add(adaptDeviceElement); DataModel.Catalog.DeviceElements.Add(adaptDeviceElement); } else { //Connectors are not represented as DeviceElements in ADAPT AddConnector(rootDeviceElementHierarchy, isoDeviceElement); } } } return(adaptDeviceElements); }
private static MachineConfiguration AddMachineConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy deviceHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { MachineConfiguration machineConfig = new MachineConfiguration(); //Description machineConfig.Description = $"{deviceHierarchy.DeviceElement.Device.DeviceDesignator} : {deviceHierarchy.DeviceElement.DeviceElementDesignator}"; //Device Element ID machineConfig.DeviceElementId = adaptDeviceElement.Id.ReferenceId; //Offsets if (deviceHierarchy.XOffset.HasValue || deviceHierarchy.YOffset.HasValue || deviceHierarchy.ZOffset.HasValue) { machineConfig.Offsets = new List <NumericRepresentationValue>(); if (deviceHierarchy.XOffset != null) { machineConfig.Offsets.Add(deviceHierarchy.XOffsetRepresentation); } if (deviceHierarchy.YOffset != null) { machineConfig.Offsets.Add(deviceHierarchy.YOffsetRepresentation); } if (deviceHierarchy.ZOffset != null) { machineConfig.Offsets.Add(deviceHierarchy.ZOffsetRepresentation); } } //GPS Offsets if (deviceHierarchy.Children != null && deviceHierarchy.Children.Any(h => h.DeviceElement != null && h.DeviceElement.DeviceElementType == ISODeviceElementType.Navigation)) { DeviceElementHierarchy navigation = (deviceHierarchy.Children.First(h => h.DeviceElement.DeviceElementType == ISODeviceElementType.Navigation)); machineConfig.GpsReceiverXOffset = navigation.XOffsetRepresentation; machineConfig.GpsReceiverYOffset = navigation.YOffsetRepresentation; machineConfig.GpsReceiverZOffset = navigation.ZOffsetRepresentation; } catalog.DeviceElementConfigurations.Add(machineConfig); return(machineConfig); }
/// <summary> /// Adds a connector with a hitch at the given reference point, referencing the parent DeviceElement as the DeviceElementConfiguration /// </summary> /// <param name="rootDeviceHierarchy"></param> /// <param name="connectorDeviceElement"></param> /// <param name="deviceElement"></param> private void AddConnector(DeviceElementHierarchy rootDeviceHierarchy, ISODeviceElement connectorDeviceElement) { //Per the TC-GEO specification, the connector is always a child of the root device element. DeviceElementHierarchy hierarchy = rootDeviceHierarchy.FromDeviceElementID(connectorDeviceElement.DeviceElementId); if (hierarchy.Parent == rootDeviceHierarchy) { int?rootDeviceElementID = TaskDataMapper.InstanceIDMap.GetADAPTID(rootDeviceHierarchy.DeviceElement.DeviceElementId); if (rootDeviceElementID.HasValue) { HitchPoint hitch = new HitchPoint(); hitch.ReferencePoint = new ReferencePoint() { XOffset = hierarchy.XOffsetRepresentation, YOffset = hierarchy.YOffsetRepresentation, ZOffset = hierarchy.ZOffsetRepresentation }; hitch.HitchTypeEnum = HitchTypeEnum.Unkown; DataModel.Catalog.HitchPoints.Add(hitch); //Get the DeviceElementConfiguration for the root element in order that we may link the Connector to it. DeviceElement root = DataModel.Catalog.DeviceElements.FirstOrDefault(d => d.Id.ReferenceId == rootDeviceElementID); if (root != null) { DeviceElementConfiguration rootDeviceConfiguration = DeviceElementMapper.GetDeviceElementConfiguration(root, rootDeviceHierarchy, DataModel.Catalog); if (rootDeviceConfiguration != null) { Connector connector = new Connector(); ImportIDs(connector.Id, hierarchy.DeviceElement.DeviceElementId); connector.DeviceElementConfigurationId = rootDeviceConfiguration.Id.ReferenceId; connector.HitchPointId = hitch.Id.ReferenceId; DataModel.Catalog.Connectors.Add(connector); //The ID mapping will link the ADAPT Connector to the ISO Device Element TaskDataMapper.InstanceIDMap.Add(connector.Id.ReferenceId, connectorDeviceElement.DeviceElementId); } } } } }
private static SectionConfiguration AddSectionConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy deviceHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { SectionConfiguration sectionConfiguration = new SectionConfiguration(); //Description sectionConfiguration.Description = $"{deviceHierarchy.DeviceElement.Device.DeviceDesignator} : {deviceHierarchy.DeviceElement.DeviceElementDesignator}"; //Device Element ID sectionConfiguration.DeviceElementId = adaptDeviceElement.Id.ReferenceId; NumericRepresentationValue width = deviceHierarchy.WidthRepresentation; NumericRepresentationValue xOffset = deviceHierarchy.XOffsetRepresentation; NumericRepresentationValue yOffset = deviceHierarchy.YOffsetRepresentation; if (adaptDeviceElement.DeviceElementType == DeviceElementTypeEnum.Bin) { //A bin carries no geometry information and should inherit width from its parent and carry 0 offsets from its parent. width = deviceHierarchy.Parent.WidthRepresentation; xOffset = 0.AsNumericRepresentationValue("0086", deviceHierarchy.RepresentationMapper); yOffset = 0.AsNumericRepresentationValue("0087", deviceHierarchy.RepresentationMapper); } //Width & Offsets sectionConfiguration.SectionWidth = width; sectionConfiguration.Offsets = new List <NumericRepresentationValue>(); if (xOffset != null) { sectionConfiguration.InlineOffset = xOffset; sectionConfiguration.Offsets.Add(xOffset); } if (yOffset != null) { sectionConfiguration.LateralOffset = yOffset; sectionConfiguration.Offsets.Add(yOffset); } catalog.DeviceElementConfigurations.Add(sectionConfiguration); return(sectionConfiguration); }
public static DeviceElementConfiguration GetDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy isoHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { if ((isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Bin && (isoHierarchy.Parent.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Function || isoHierarchy.Parent.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Device)) || (isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Connector) || (isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Navigation)) { //Data belongs to the parent device element from the ISO element referenced //Bin children of functions or devices carry data that effectively belong to the parent device element in ISO. See TC-GEO examples 5-8. //Find the parent DeviceElementUse and add the data to that object. //Per the TC-GEO spec: "The location of the Bin type device elements as children of the boom specifies that the products from these bins are all distributed through that boom." //- //Also, Connector and Navigation data may be stored in Timelog data, but Connectors are not DeviceElements in ADAPT. The data refers to the parent implement. DeviceElementConfiguration parentConfig = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == adaptDeviceElement.ParentDeviceId); if (parentConfig == null) { DeviceElement parentElement = catalog.DeviceElements.Single(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); parentConfig = AddDeviceElementConfiguration(parentElement, isoHierarchy.Parent, catalog); } return(parentConfig); } else { DeviceElementConfiguration deviceConfiguration = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == adaptDeviceElement.Id.ReferenceId); if (deviceConfiguration == null) { deviceConfiguration = AddDeviceElementConfiguration(adaptDeviceElement, isoHierarchy, catalog); } return(deviceConfiguration); } }
private void UpdateCondensedWorkingDatas(List <ISOEnumeratedMeter> condensedWorkingDatas, ISODataLogValue dlv, DeviceElementUse deviceElementUse, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(dlv.DeviceElementIdRef); List <ISODeviceElement> isoSectionElements = isoDeviceElement.ChildDeviceElements.Where(d => d.DeviceElementType == ISOEnumerations.ISODeviceElementType.Section).ToList(); //We have some sections in the DDOP if (isoSectionElements.Count > 0) { //Update the DeviceElementReference on the Condensed WorkingDatas foreach (var workingData in condensedWorkingDatas) { if (workingData.SectionIndex - 1 >= isoSectionElements.Count) { break; } ISODeviceElement targetSection = isoSectionElements[workingData.SectionIndex - 1]; DeviceElementUse condensedDeviceElementUse = FindExistingDeviceElementUseForCondensedData(targetSection, pendingDeviceElementUses); if (condensedDeviceElementUse == null) { //Make a new DeviceElementUse condensedDeviceElementUse = new DeviceElementUse(); condensedDeviceElementUse.OperationDataId = deviceElementUse.OperationDataId; int?deviceElementID = TaskDataMapper.InstanceIDMap.GetADAPTID(targetSection.DeviceElementId); if (deviceElementID.HasValue) { DeviceElement deviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == deviceElementID.Value); if (deviceElement != null) { //Reference the device element in its hierarchy so that we can get the depth & order DeviceElementHierarchy deviceElementInHierarchy = isoDeviceElementHierarchy.FromDeviceElementID(targetSection.DeviceElementId); //Get the config id DeviceElementConfiguration deviceElementConfig = DeviceElementMapper.GetDeviceElementConfiguration(deviceElement, deviceElementInHierarchy, DataModel.Catalog); condensedDeviceElementUse.DeviceConfigurationId = deviceElementConfig.Id.ReferenceId; //Set the depth & order condensedDeviceElementUse.Depth = deviceElementInHierarchy.Depth; condensedDeviceElementUse.Order = deviceElementInHierarchy.Order; } } condensedDeviceElementUse.GetWorkingDatas = () => new List <WorkingData> { workingData }; workingData.DeviceElementUseId = condensedDeviceElementUse.Id.ReferenceId; pendingDeviceElementUses.Add(condensedDeviceElementUse); } else { //Use the existing DeviceElementUse List <WorkingData> data = new List <WorkingData>(); IEnumerable <WorkingData> existingWorkingDatas = condensedDeviceElementUse.GetWorkingDatas(); if (existingWorkingDatas != null) { data.AddRange(existingWorkingDatas.ToList()); //Add the preexisting } data.Add(workingData); condensedDeviceElementUse.GetWorkingDatas = () => data; } } } }
private static ImplementConfiguration AddImplementConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy deviceHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { ImplementConfiguration implementConfig = new ImplementConfiguration(); //Description implementConfig.Description = $"{deviceHierarchy.DeviceElement.Device.DeviceDesignator} : {deviceHierarchy.DeviceElement.DeviceElementDesignator}"; //Device Element ID implementConfig.DeviceElementId = adaptDeviceElement.Id.ReferenceId; //Offsets implementConfig.Offsets = new List <NumericRepresentationValue>(); if (deviceHierarchy.XOffsetRepresentation != null) { implementConfig.Offsets.Add(deviceHierarchy.XOffsetRepresentation); } if (deviceHierarchy.YOffsetRepresentation != null) { implementConfig.Offsets.Add(deviceHierarchy.YOffsetRepresentation); } if (deviceHierarchy.ZOffsetRepresentation != null) { implementConfig.Offsets.Add(deviceHierarchy.ZOffsetRepresentation); } //Total Width if (deviceHierarchy.Width != null) { implementConfig.PhysicalWidth = deviceHierarchy.WidthRepresentation; } //Row Width NumericRepresentationValue rowWidth = deviceHierarchy.GetLowestLevelSectionWidth(); if (rowWidth != null) { implementConfig.Width = rowWidth; } catalog.DeviceElementConfigurations.Add(implementConfig); return(implementConfig); }
public static DeviceElementConfiguration GetDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy isoHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { if (isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Connector || isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Navigation) { //Data belongs to the parent device element from the ISO element referenced //Connector and Navigation data may be stored in Timelog data, but Connectors are not DeviceElements in ADAPT. //The data refers to the parent implement, which must always be a Device DET per the ISO spec. DeviceElement parent = catalog.DeviceElements.FirstOrDefault(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); while (parent != null && (parent.DeviceElementType != DeviceElementTypeEnum.Machine && parent.DeviceElementType != DeviceElementTypeEnum.Implement)) { parent = catalog.DeviceElements.FirstOrDefault(d => d.Id.ReferenceId == parent.ParentDeviceId); } if (parent == null) { throw new ApplicationException($"Cannot identify Device for Navigation/Connector DeviceElement: {adaptDeviceElement.Description}."); } DeviceElementConfiguration parentConfig = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == parent.Id.ReferenceId); if (parentConfig == null) { DeviceElement parentElement = catalog.DeviceElements.Single(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); parentConfig = AddDeviceElementConfiguration(parentElement, isoHierarchy.Parent, catalog); } return(parentConfig); } else { DeviceElementConfiguration deviceConfiguration = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == adaptDeviceElement.Id.ReferenceId); if (deviceConfiguration == null) { deviceConfiguration = AddDeviceElementConfiguration(adaptDeviceElement, isoHierarchy, catalog); } return(deviceConfiguration); } }
private static DeviceElementConfiguration AddDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy isoHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { switch (adaptDeviceElement.DeviceElementType) { case DeviceElementTypeEnum.Machine: return(AddMachineConfiguration(adaptDeviceElement, isoHierarchy, catalog)); case DeviceElementTypeEnum.Implement: return(AddImplementConfiguration(adaptDeviceElement, isoHierarchy, catalog)); case DeviceElementTypeEnum.Function: if (isoHierarchy.Parent.DeviceElement.DeviceElementType == ISODeviceElementType.Function) { //Function is part of the implement. I.e., TC-GEO example 9 / ISO 11783-10:2015(E) Figure F.24 return(AddSectionConfiguration(adaptDeviceElement, isoHierarchy, catalog)); } else { //Function is the entire implement return(AddImplementConfiguration(adaptDeviceElement, isoHierarchy, catalog)); } case DeviceElementTypeEnum.Section: case DeviceElementTypeEnum.Bin: case DeviceElementTypeEnum.Unit: return(AddSectionConfiguration(adaptDeviceElement, isoHierarchy, catalog)); default: return(null); } }
public DeviceElement ImportDeviceElement(ISODeviceElement isoDeviceElement, EnumeratedValue deviceClassification, DeviceElementHierarchy rootDeviceHierarchy) { DeviceElement deviceElement = new DeviceElement(); //ID ImportIDs(deviceElement.Id, isoDeviceElement.DeviceElementId); //Device ID int?deviceModelId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElement.Device.DeviceId); if (deviceModelId.HasValue) { deviceElement.DeviceModelId = deviceModelId.Value; } //Description deviceElement.Description = isoDeviceElement.DeviceElementDesignator; //Classification deviceElement.DeviceClassification = deviceClassification; //Parent ID if (isoDeviceElement.Parent != null) { int?parentDeviceId = null; if (isoDeviceElement.ParentObjectId == isoDeviceElement.DeviceElementObjectId) { //Element has listed itself as its own parent. Do not include a parent on the adapt element as it will invalidate logic in the hierarchy creation. } else if (isoDeviceElement.Parent is ISODeviceElement parentElement) { parentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(parentElement.DeviceElementId); } else if (isoDeviceElement.Parent is ISODevice parentDevice) { parentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(parentDevice.DeviceId); } if (parentDeviceId.HasValue) { deviceElement.ParentDeviceId = parentDeviceId.Value; } } DeviceElementHierarchy deviceElementHierarchy = TaskDataMapper.DeviceElementHierarchies.GetRelevantHierarchy(isoDeviceElement.DeviceElementId); //Device Element Type switch (isoDeviceElement.DeviceElementType) { case ISODeviceElementType.Device: //This is the root device element if (deviceClassification != null && deviceClassification.Value != null && TaskDataMapper.DeviceOperationTypes.First(d => d.MachineEnumerationMember.DomainTag == deviceClassification.Value.Code).HasMachineConfiguration) { //Device is a machine deviceElement.DeviceElementType = DeviceElementTypeEnum.Machine; } else if (deviceElementHierarchy.Children != null && deviceElementHierarchy.Children.Any(d => d?.DeviceElement.DeviceElementType == ISODeviceElementType.Navigation) && //The Nav element should be a direct descendant of the root (!deviceElementHierarchy.Children.Any(d => d?.DeviceElement.DeviceElementType == ISODeviceElementType.Section) && //If there are section or function elements, classify as an implement vs. a machine !deviceElementHierarchy.Children.Any(d => d?.DeviceElement.DeviceElementType == ISODeviceElementType.Function))) { //Device is a machine deviceElement.DeviceElementType = DeviceElementTypeEnum.Machine; } else { //Default: classify as an implement deviceElement.DeviceElementType = DeviceElementTypeEnum.Implement; } break; case ISODeviceElementType.Bin: deviceElement.DeviceElementType = DeviceElementTypeEnum.Bin; break; case ISODeviceElementType.Function: deviceElement.DeviceElementType = DeviceElementTypeEnum.Function; break; case ISODeviceElementType.Section: deviceElement.DeviceElementType = DeviceElementTypeEnum.Section; break; case ISODeviceElementType.Unit: deviceElement.DeviceElementType = DeviceElementTypeEnum.Unit; break; case ISODeviceElementType.Navigation: deviceElement.DeviceElementType = DeviceElementTypeEnum.Function; break; } if (HasGeometryInformation(deviceElementHierarchy)) { //Geometry information is on DeviceProperty elements. GetDeviceElementConfiguration(deviceElement, deviceElementHierarchy, DataModel.Catalog); //Add via the Get method to invoke business rules for configs } return(deviceElement); }
private bool HasGeometryInformation(DeviceElementHierarchy deviceElementHierarchy) { return(deviceElementHierarchy.Width.HasValue || deviceElementHierarchy.XOffset.HasValue || deviceElementHierarchy.YOffset.HasValue || deviceElementHierarchy.ZOffset.HasValue); }
public List <DeviceElementUse> Map(ISOTime time, IEnumerable <ISOSpatialRow> isoRecords, int operationDataId, IEnumerable <string> isoDeviceElementIDs, Dictionary <string, List <ISOProductAllocation> > isoProductAllocations) { var sections = new List <DeviceElementUse>(); foreach (string isoDeviceElementID in isoDeviceElementIDs) { DeviceElementHierarchy hierarchy = TaskDataMapper.DeviceElementHierarchies.GetRelevantHierarchy(isoDeviceElementID); if (hierarchy != null) { DeviceElementUse deviceElementUse = null; List <WorkingData> workingDatas = new List <WorkingData>(); //Get the relevant DeviceElementConfiguration int adaptDeviceElementId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElementID).Value; DeviceElement adaptDeviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == adaptDeviceElementId); if (adaptDeviceElement != null) { DeviceElementConfiguration config = DeviceElementMapper.GetDeviceElementConfiguration(adaptDeviceElement, hierarchy, DataModel.Catalog); int depth = hierarchy.Depth; int order = hierarchy.Order; if (config.DeviceElementId == adaptDeviceElement.ParentDeviceId) { //The configuration references the parent ISO element depth = hierarchy.Parent.Depth; order = hierarchy.Parent.Order; } //Read any spatially-listed widths/offsets on this data onto the DeviceElementConfiguration objects hierarchy.SetWidthsAndOffsetsFromSpatialData(time, isoRecords, config, RepresentationMapper); 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, hierarchy, sections, isoProductAllocations); if (data.Any()) { workingDatas.AddRange(data); } } else { workingDatas = deviceElementUse.GetWorkingDatas().ToList(); //Add Additional Working Data List <WorkingData> data = _workingDataMapper.Map(time, isoRecords, deviceElementUse, hierarchy, sections, isoProductAllocations); if (data.Any()) { workingDatas.AddRange(data); } } deviceElementUse.GetWorkingDatas = () => workingDatas; if (!sections.Contains(deviceElementUse)) { sections.Add(deviceElementUse); } } else if (hierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Connector) { int?connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(hierarchy.DeviceElement.DeviceElementId).Value; if (connectorID.HasValue) { Connector adaptConnector = DataModel.Catalog.Connectors.FirstOrDefault(c => c.Id.ReferenceId == connectorID.Value); if (adaptConnector != null) { HitchPoint hitch = DataModel.Catalog.HitchPoints.FirstOrDefault(h => h.Id.ReferenceId == adaptConnector.HitchPointId); if (hitch != null) { hierarchy.SetHitchOffsetsFromSpatialData(time, isoRecords, hitch, RepresentationMapper); } } } } } } return(sections); }
private IEnumerable <WorkingData> Map(ISODataLogValue dlv, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, int order, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { var workingDatas = new List <WorkingData>(); if (_ddis.ContainsKey(dlv.ProcessDataDDI.AsInt32DDI())) { //Numeric Representations NumericWorkingData numericMeter = MapNumericMeter(dlv, deviceElementUse.Id.ReferenceId); DataLogValuesByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(numericMeter); return(workingDatas); } var meterCreator = _enumeratedMeterCreatorFactory.GetMeterCreator(dlv.ProcessDataDDI.AsInt32DDI()); if (meterCreator != null) { //Enumerated Representations var isoEnumeratedMeters = meterCreator.CreateMeters(isoSpatialRows); foreach (ISOEnumeratedMeter enumeratedMeter in isoEnumeratedMeters) { DataLogValuesByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv.DeviceElementIdRef); enumeratedMeter.DeviceElementUseId = deviceElementUse.Id.ReferenceId; } workingDatas.AddRange(isoEnumeratedMeters); if (meterCreator is CondensedStateMeterCreator) { UpdateCondensedWorkingDatas(workingDatas, dlv, deviceElementUse, pendingDeviceElementUses, isoDeviceElementHierarchy); } } else { //Proprietary DDIs - report out as numeric value NumericWorkingData proprietaryWorkingData = new NumericWorkingData(); proprietaryWorkingData.Representation = new ApplicationDataModel.Representations.NumericRepresentation { Code = dlv.ProcessDataDDI, CodeSource = RepresentationCodeSourceEnum.ISO11783_DDI }; proprietaryWorkingData.DeviceElementUseId = deviceElementUse.Id.ReferenceId; //Take any information from DPDs/DVPs ApplicationDataModel.Common.UnitOfMeasure uom = null; ISODeviceElement det = isoDeviceElementHierarchy.DeviceElement; if (det != null) { ISODeviceProcessData dpd = det.DeviceProcessDatas.FirstOrDefault(d => d.DDI == dlv.ProcessDataDDI); if (dpd != null) { proprietaryWorkingData.Representation.Description = dpd.Designator; //Update the representation with a name since we have one here. ISODeviceValuePresentation dvp = det.Device.DeviceValuePresentations.FirstOrDefault(d => d.ObjectID == dpd.DeviceValuePresentationObjectId); if (dvp != null && dvp.UnitDesignator != null) { if (AgGateway.ADAPT.Representation.UnitSystem.InternalUnitSystemManager.Instance.UnitOfMeasures.Contains(dvp.UnitDesignator)) { //The unit designator used by the OEM will need to match ADAPT for this to work, otherwise we'll need to default to 'count' below //It will likely work for many simple units and will not for work compound units uom = UnitSystemManager.GetUnitOfMeasure(dvp.UnitDesignator); } } } } proprietaryWorkingData.UnitOfMeasure = uom ?? UnitSystemManager.GetUnitOfMeasure("count"); //Best we can do DataLogValuesByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(proprietaryWorkingData); } return(workingDatas); }
private IEnumerable <WorkingData> Map(ISODataLogValue dlv, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, int order, List <DeviceElementUse> pendingDeviceElementUses, DeviceElementHierarchy isoDeviceElementHierarchy) { var workingDatas = new List <WorkingData>(); if (_ddis.ContainsKey(dlv.ProcessDataDDI.AsInt32DDI())) { //Numeric Representations NumericWorkingData numericMeter = MapNumericMeter(dlv, deviceElementUse.Id.ReferenceId); DataLogValuesByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(numericMeter.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(numericMeter); return(workingDatas); } var meterCreator = _enumeratedMeterCreatorFactory.GetMeterCreator(dlv.ProcessDataDDI.AsInt32DDI()); if (meterCreator != null) { //Enumerated Representations var isoEnumeratedMeters = meterCreator.CreateMeters(isoSpatialRows, dlv); foreach (ISOEnumeratedMeter enumeratedMeter in isoEnumeratedMeters) { DataLogValuesByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(enumeratedMeter.Id.ReferenceId, dlv.DeviceElementIdRef); enumeratedMeter.DeviceElementUseId = deviceElementUse.Id.ReferenceId; } workingDatas.AddRange(isoEnumeratedMeters); if (meterCreator is CondensedStateMeterCreator) { UpdateCondensedWorkingDatas(workingDatas, dlv, deviceElementUse, pendingDeviceElementUses, isoDeviceElementHierarchy); } } else { //Proprietary DDIs - report out as numeric value NumericWorkingData proprietaryWorkingData = new NumericWorkingData(); proprietaryWorkingData.Representation = new ApplicationDataModel.Representations.NumericRepresentation { Code = dlv.ProcessDataDDI, CodeSource = RepresentationCodeSourceEnum.ISO11783_DDI }; proprietaryWorkingData.DeviceElementUseId = deviceElementUse.Id.ReferenceId; //Always set unit as count. In SpatialRecordMapper, we will place the DVP unit on the NumericRepresentationValue.UserProvidedUnitOfMeasure //so that consumers can apply any offset/scaling to get to the desired display unit. proprietaryWorkingData.UnitOfMeasure = UnitSystemManager.GetUnitOfMeasure("count"); //Take any information from DPD ISODeviceElement det = isoDeviceElementHierarchy.DeviceElement; if (det != null) { ISODeviceProcessData dpd = det.DeviceProcessDatas.FirstOrDefault(d => d.DDI == dlv.ProcessDataDDI); if (dpd != null) { proprietaryWorkingData.Representation.Description = dpd.Designator; //Update the representation with a name since we have one here. } } DataLogValuesByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv); ISODeviceElementIDsByWorkingDataID.Add(proprietaryWorkingData.Id.ReferenceId, dlv.DeviceElementIdRef); workingDatas.Add(proprietaryWorkingData); } return(workingDatas); }
private static SectionConfiguration AddSectionConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy deviceHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { SectionConfiguration sectionConfiguration = new SectionConfiguration(); //Description sectionConfiguration.Description = $"{deviceHierarchy.DeviceElement.Device.DeviceDesignator} : {deviceHierarchy.DeviceElement.DeviceElementDesignator}"; //Device Element ID sectionConfiguration.DeviceElementId = adaptDeviceElement.Id.ReferenceId; //Width & Offsets if (deviceHierarchy.Width != null) { sectionConfiguration.SectionWidth = deviceHierarchy.WidthRepresentation; } sectionConfiguration.Offsets = new List <NumericRepresentationValue>(); if (deviceHierarchy.XOffset != null) { sectionConfiguration.InlineOffset = deviceHierarchy.XOffsetRepresentation; sectionConfiguration.Offsets.Add(deviceHierarchy.XOffsetRepresentation); } if (deviceHierarchy.YOffset != null) { sectionConfiguration.LateralOffset = deviceHierarchy.YOffsetRepresentation; sectionConfiguration.Offsets.Add(deviceHierarchy.YOffsetRepresentation); } catalog.DeviceElementConfigurations.Add(sectionConfiguration); return(sectionConfiguration); }
public DeviceElement ImportDeviceElement(ISODeviceElement isoDeviceElement, EnumeratedValue deviceClassification, DeviceElementHierarchy rootDeviceHierarchy) { DeviceElement deviceElement = new DeviceElement(); //ID ImportIDs(deviceElement.Id, isoDeviceElement.DeviceElementId); //Device ID deviceElement.DeviceModelId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoDeviceElement.Device.DeviceId).Value; //Description deviceElement.Description = isoDeviceElement.DeviceElementDesignator; //Classification deviceElement.DeviceClassification = deviceClassification; //Parent ID if (isoDeviceElement.Parent != null) { if (isoDeviceElement.Parent is ISODeviceElement) { ISODeviceElement parentElement = isoDeviceElement.Parent as ISODeviceElement; deviceElement.ParentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(parentElement.DeviceElementId).Value; } else { ISODevice parentDevice = isoDeviceElement.Parent as ISODevice; deviceElement.ParentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(parentDevice.DeviceId).Value; } } DeviceElementHierarchy deviceElementHierarchy = TaskDataMapper.DeviceElementHierarchies.GetRelevantHierarchy(isoDeviceElement.DeviceElementId); //Device Element Type switch (isoDeviceElement.DeviceElementType) { case ISODeviceElementType.Device: //This is the root device element if (deviceClassification != null && deviceClassification.Value != null && TaskDataMapper.DeviceOperationTypes.First(d => d.MachineEnumerationMember.DomainTag == deviceClassification.Value.Code).HasMachineConfiguration) { //Device is a machine deviceElement.DeviceElementType = DeviceElementTypeEnum.Machine; } else if (deviceElementHierarchy.Children != null && deviceElementHierarchy.Children.Any(h => h.DeviceElement != null && h.DeviceElement.DeviceElementType == ISODeviceElementType.Navigation)) { //Device has a navigation element; classify as a machine deviceElement.DeviceElementType = DeviceElementTypeEnum.Machine; } else { //Default: classify as an implement deviceElement.DeviceElementType = DeviceElementTypeEnum.Implement; } break; case ISODeviceElementType.Bin: deviceElement.DeviceElementType = DeviceElementTypeEnum.Bin; break; case ISODeviceElementType.Function: deviceElement.DeviceElementType = DeviceElementTypeEnum.Function; break; case ISODeviceElementType.Section: deviceElement.DeviceElementType = DeviceElementTypeEnum.Section; break; case ISODeviceElementType.Unit: deviceElement.DeviceElementType = DeviceElementTypeEnum.Unit; break; case ISODeviceElementType.Navigation: deviceElement.DeviceElementType = DeviceElementTypeEnum.Function; break; } if (HasGeometryInformation(deviceElementHierarchy)) { //Geometry information is on DeviceProperty elements. GetDeviceElementConfiguration(deviceElement, deviceElementHierarchy, DataModel.Catalog); //Add via the Get method to invoke business rules for configs } return(deviceElement); }
public List <WorkingData> Map(ISOTime time, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, DeviceElementHierarchy isoDeviceElementHierarchy, List <DeviceElementUse> pendingDeviceElementUses) { var workingDatas = new List <WorkingData>(); //Set orders on the collection of DLVs var allDLVs = time.DataLogValues; for (int order = 0; order < allDLVs.Count(); order++) { var dlv = allDLVs.ElementAt(order); dlv.Order = order; } //Add the Working Datas for this DeviceElement IEnumerable <ISODataLogValue> deviceElementDLVs = allDLVs.Where(dlv => dlv.DeviceElementIdRef == isoDeviceElementHierarchy.DeviceElement.DeviceElementId); foreach (ISODataLogValue dlv in deviceElementDLVs) { IEnumerable <WorkingData> newWorkingDatas = Map(dlv, isoSpatialRows, deviceElementUse, dlv.Order, pendingDeviceElementUses, isoDeviceElementHierarchy); if (newWorkingDatas.Count() > 0) { int ddi = dlv.ProcessDataDDI.AsInt32DDI(); if (!EnumeratedMeterFactory.IsCondensedMeter(ddi)) { //We skip adding Condensed WorkingDatas to this DeviceElementUse since they were added separately below to their specific DeviceElementUse workingDatas.AddRange(newWorkingDatas); } } } return(workingDatas); }
public static DeviceElementConfiguration GetDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceElementHierarchy isoHierarchy, AgGateway.ADAPT.ApplicationDataModel.ADM.Catalog catalog) { if (isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Connector || isoHierarchy.DeviceElement.DeviceElementType == ISOEnumerations.ISODeviceElementType.Navigation) { //Data belongs to the parent device element from the ISO element referenced //Connector and Navigation data may be stored in Timelog data, but Connectors are not DeviceElements in ADAPT. The data refers to the parent implement. DeviceElementConfiguration parentConfig = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == adaptDeviceElement.ParentDeviceId); if (parentConfig == null) { DeviceElement parentElement = catalog.DeviceElements.Single(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); parentConfig = AddDeviceElementConfiguration(parentElement, isoHierarchy.Parent, catalog); } return(parentConfig); } else { DeviceElementConfiguration deviceConfiguration = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.DeviceElementId == adaptDeviceElement.Id.ReferenceId); if (deviceConfiguration == null) { deviceConfiguration = AddDeviceElementConfiguration(adaptDeviceElement, isoHierarchy, catalog); } return(deviceConfiguration); } }