private int GetLowestProductAllocationLevel(DeviceHierarchyElement isoDeviceElementHierarchy, Dictionary <string, List <ISOProductAllocation> > isoProductAllocations) { int level = -1; // If device element has direct product allocations, use its Depth. if (isoDeviceElementHierarchy != null && isoProductAllocations.TryGetValue(isoDeviceElementHierarchy.DeviceElement.DeviceElementId, out List <ISOProductAllocation> productAllocations) && productAllocations.Any(x => x.DeviceElementIdRef == isoDeviceElementHierarchy.DeviceElement.DeviceElementId)) { level = isoDeviceElementHierarchy.Depth; } // Get max level from children elements int?maxChildLevel = isoDeviceElementHierarchy?.Children?.Max(x => GetLowestProductAllocationLevel(x, isoProductAllocations)); return(Math.Max(level, maxChildLevel.GetValueOrDefault(-1))); }
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); } DeviceHierarchyElement 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); 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); }
public List <WorkingData> Map(ISOTime time, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, DeviceHierarchyElement isoDeviceElementHierarchy, List <DeviceElementUse> pendingDeviceElementUses, Dictionary <string, List <ISOProductAllocation> > isoProductAllocations) { var workingDatas = new List <WorkingData>(); //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 = time.DataLogValues.Where(dlv => dlv.DeviceElementIdRef == isoDeviceElementHierarchy.DeviceElement.DeviceElementId || //DLV DET reference matches the primary DET for the ADAPT element isoDeviceElementHierarchy.MergedElements.Any(e => e.DeviceElementId == dlv.DeviceElementIdRef)); //DLV DET reference matches one of the merged DETs on the ADAPT element foreach (ISODataLogValue dlv in deviceElementDLVs) { IEnumerable <WorkingData> newWorkingDatas = Map(dlv, isoSpatialRows, deviceElementUse, dlv.Index, 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 static MachineConfiguration AddMachineConfiguration(DeviceElement adaptDeviceElement, DeviceHierarchyElement 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)) { DeviceHierarchyElement 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); }
private Dictionary <string, List <ISOProductAllocation> > GetProductAllocationsByDeviceElement(ISOTask loggedTask, ISODevice dvc) { Dictionary <string, Dictionary <string, ISOProductAllocation> > reportedPANs = new Dictionary <string, Dictionary <string, ISOProductAllocation> >(); int panIndex = 0; // This supports multiple direct PANs for the same DET foreach (ISOProductAllocation pan in loggedTask.ProductAllocations.Where(p => !string.IsNullOrEmpty(p.DeviceElementIdRef))) { ISODeviceElement deviceElement = dvc.DeviceElements.FirstOrDefault(d => d.DeviceElementId == pan.DeviceElementIdRef); if (deviceElement != null) //Filter PANs by this DVC { AddProductAllocationsForDeviceElement(reportedPANs, pan, deviceElement, $"{GetHierarchyPosition(deviceElement)}_{panIndex}"); } panIndex++; } // Sort product allocations for each DeviceElement using it's position among ancestors. // This arranges PANs on each DET in reverse order: ones from lowest DET in hierarchy having precedence over ones from top. Dictionary <string, List <ISOProductAllocation> > output = reportedPANs.ToDictionary(x => x.Key, x => { var allocations = x.Value.OrderByDescending(y => y.Key).Select(y => y.Value).ToList(); // Check if there are any indirect allocations: ones that came from parent device element var indirectAllocations = allocations.Where(y => y.DeviceElementIdRef != x.Key).ToList(); if (indirectAllocations.Count > 0 && indirectAllocations.Count != allocations.Count) { // Only keep direct allocations allocations = allocations.Except(indirectAllocations).ToList(); } return(allocations); }); // Determine the lowest depth at which product allocations are reported to eliminate any duplicate PANs // at multiple levels within the hierarchy DeviceHierarchyElement det = reportedPANs.Keys .Select(x => TaskDataMapper.DeviceElementHierarchies.GetMatchingElement(x)) .Where(x => x != null) .FirstOrDefault(); int lowestLevel = GetLowestProductAllocationLevel(det?.GetRootDeviceElementHierarchy(), output); // Remove allocations for all other levels return(output .Where(x => TaskDataMapper.DeviceElementHierarchies.GetMatchingElement(x.Key)?.Depth == lowestLevel) .ToDictionary(x => x.Key, x => x.Value)); }
/// <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(DeviceHierarchyElement rootDeviceHierarchy, ISODeviceElement connectorDeviceElement) { //Per the TC-GEO specification, the connector is always a child of the root device element. DeviceHierarchyElement hierarchyElement = rootDeviceHierarchy.FromDeviceElementID(connectorDeviceElement.DeviceElementId); if (hierarchyElement.Parent == rootDeviceHierarchy) { int?rootDeviceElementID = TaskDataMapper.InstanceIDMap.GetADAPTID(rootDeviceHierarchy.DeviceElement.DeviceElementId); if (rootDeviceElementID.HasValue) { HitchPoint hitch = new HitchPoint(); hitch.ReferencePoint = new ReferencePoint() { XOffset = hierarchyElement.XOffsetRepresentation, YOffset = hierarchyElement.YOffsetRepresentation, ZOffset = hierarchyElement.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, hierarchyElement.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 void UpdateCondensedWorkingDatas(List <ISOEnumeratedMeter> condensedWorkingDatas, ISODataLogValue dlv, DeviceElementUse deviceElementUse, List <DeviceElementUse> pendingDeviceElementUses, DeviceHierarchyElement isoDeviceElementHierarchy) { ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(dlv.DeviceElementIdRef); List <ISODeviceElement> isoSectionElements = isoDeviceElement.ChildDeviceElements.Where(d => d.DeviceElementType == ISOEnumerations.ISODeviceElementType.Section).ToList(); foreach (var subElement in isoDeviceElement.ChildDeviceElements) { //This handles cases where the condensed workstate is reported on a top-level boom with sub-booms in the hierarchy above the sections (e.g., ISO 11783-10:2015(E) Figure F.35) isoSectionElements.AddRange(subElement.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 DeviceHierarchyElement 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; } } } }
/// <summary> /// This method returns multiple WorkingData objects for a single DLV in the ISO model /// to handle the Condensed DDI case where a single DLV can contain multiple logical /// data points. For non-condensed DDIs, the method will return a single item in output enumerable. /// </summary> /// <param name="dlv"></param> /// <param name="isoSpatialRows"></param> /// <param name="deviceElementUse"></param> /// <param name="order"></param> /// <param name="pendingDeviceElementUses"></param> /// <param name="isoDeviceElementHierarchy"></param> /// <returns></returns> private IEnumerable <WorkingData> Map(ISODataLogValue dlv, IEnumerable <ISOSpatialRow> isoSpatialRows, DeviceElementUse deviceElementUse, byte order, List <DeviceElementUse> pendingDeviceElementUses, DeviceHierarchyElement 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.Cast <ISOEnumeratedMeter>().ToList(), 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 ?? isoDeviceElementHierarchy.MergedElements.FirstOrDefault(me => me.DeviceElementId == dlv.DeviceElementIdRef); 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); }
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) { 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; DeviceElement adaptDeviceElement = DataModel.Catalog.DeviceElements.SingleOrDefault(d => d.Id.ReferenceId == adaptDeviceElementId); if (adaptDeviceElement != null) { DeviceElementConfiguration config = DeviceElementMapper.GetDeviceElementConfiguration(adaptDeviceElement, hierarchyElement, DataModel.Catalog); int depth = hierarchyElement.Depth; int order = hierarchyElement.Order; if (config.DeviceElementId == adaptDeviceElement.ParentDeviceId) { //The configuration references the parent ISO element depth = hierarchyElement.Parent.Depth; order = hierarchyElement.Parent.Order; } 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()) { workingDatas.AddRange(data); } } 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); } } deviceElementUse.GetWorkingDatas = () => workingDatas; if (!sections.Contains(deviceElementUse)) { sections.Add(deviceElementUse); } } } } return(sections); }
private static SectionConfiguration AddSectionConfiguration(DeviceElement adaptDeviceElement, DeviceHierarchyElement 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); }
private static ImplementConfiguration AddImplementConfiguration(DeviceElement adaptDeviceElement, DeviceHierarchyElement 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) { //In an earlier implementation, we used Width for an individual Row Width and Physical Width for the max width. //Going forward, we are adopting a more conventional definition that Width is any reported width of the implement, and //Physical width is a reported max width specifically. //Widths set from Timelog binaries will have already observed this convention as they did not contain the row width variation. implementConfig.Width = deviceHierarchy.WidthRepresentation; if (deviceHierarchy.WidthDDI == "0046") { implementConfig.PhysicalWidth = deviceHierarchy.WidthRepresentation; } } catalog.DeviceElementConfigurations.Add(implementConfig); return(implementConfig); }
private static DeviceElementConfiguration AddDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceHierarchyElement 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 static DeviceElementConfiguration GetDeviceElementConfiguration(DeviceElement adaptDeviceElement, DeviceHierarchyElement 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 bool HasGeometryInformation(DeviceHierarchyElement deviceHierarchyElement) { return(deviceHierarchyElement.Width.HasValue || deviceHierarchyElement.XOffset.HasValue || deviceHierarchyElement.YOffset.HasValue || deviceHierarchyElement.ZOffset.HasValue); }
public DeviceElement ImportDeviceElement(ISODeviceElement isoDeviceElement, EnumeratedValue deviceClassification) { DeviceElement deviceElement = new DeviceElement(); DeviceHierarchyElement deviceElementHierarchy = TaskDataMapper.DeviceElementHierarchies.GetMatchingElement(isoDeviceElement.DeviceElementId); //ID ImportIDs(deviceElement.Id, isoDeviceElement.DeviceElementId); deviceElement.ContextItems = ImportContextItems(isoDeviceElement.DeviceElementId, "ADAPT_Context_Items:DeviceElement", isoDeviceElement); //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) { //Read the parent off of the DeviceElementHierarchy in case we merged the parent into another DeviceElement parentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(deviceElementHierarchy.Parent.DeviceElement.DeviceElementId); } else if (isoDeviceElement.Parent is ISODevice parentDevice) { parentDeviceId = TaskDataMapper.InstanceIDMap.GetADAPTID(parentDevice.DeviceId); } if (parentDeviceId.HasValue) { deviceElement.ParentDeviceId = parentDeviceId.Value; } } //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); }