private static SpatialValue CreateSpatialValue(ISOTime templateTime, byte order, int value, DeviceElementHierarchies deviceHierarchies) { var dataLogValues = templateTime.DataLogValues; var matchingDlv = dataLogValues.ElementAtOrDefault(order); if (matchingDlv == null) { return(null); } ISODeviceElement det = deviceHierarchies.GetISODeviceElementFromID(matchingDlv.DeviceElementIdRef); ISODevice dvc = det?.Device; ISODeviceProcessData dpd = dvc?.DeviceProcessDatas?.FirstOrDefault(d => d.DDI == matchingDlv.ProcessDataDDI); var ddis = DdiLoader.Ddis; var resolution = 1d; if (matchingDlv.ProcessDataDDI != null && ddis.ContainsKey(matchingDlv.ProcessDataDDI.AsInt32DDI())) { resolution = ddis[matchingDlv.ProcessDataDDI.AsInt32DDI()].Resolution; } var spatialValue = new SpatialValue { Id = order, DataLogValue = matchingDlv, Value = value * resolution, DeviceProcessData = dpd }; return(spatialValue); }
public DeviceElementHierarchies(IEnumerable <ISODevice> devices, RepresentationMapper representationMapper, bool mergeBins, IEnumerable <ISOTimeLog> timeLogs, string dataPath) { Items = new Dictionary <string, DeviceHierarchyElement>(); //Track any device element geometries not logged as a DPT Dictionary <string, List <string> > missingGeometryDefinitions = new Dictionary <string, List <string> >(); foreach (ISODevice device in devices) { ISODeviceElement rootDeviceElement = device.DeviceElements.SingleOrDefault(det => det.DeviceElementType == ISODeviceElementType.Device); if (rootDeviceElement != null) { DeviceHierarchyElement hierarchyElement = new DeviceHierarchyElement(rootDeviceElement, 0, representationMapper, mergeBins, missingGeometryDefinitions); hierarchyElement.HandleBinDeviceElements(); Items.Add(device.DeviceId, hierarchyElement); } } //Address the missing geometry data with targeted reads of the TLG binaries for any DPDs if (missingGeometryDefinitions.Any()) { FillDPDGeometryDefinitions(missingGeometryDefinitions, timeLogs, dataPath); } }
private IEnumerable <OperationData> ImportTimeLog(ISOTask loggedTask, ISOTimeLog isoTimeLog, int?prescriptionID) { WorkingDataMapper workingDataMapper = new WorkingDataMapper(new EnumeratedMeterFactory(), TaskDataMapper); SectionMapper sectionMapper = new SectionMapper(workingDataMapper, TaskDataMapper); SpatialRecordMapper spatialMapper = new SpatialRecordMapper(new RepresentationValueInterpolator(), sectionMapper, workingDataMapper); IEnumerable <ISOSpatialRow> isoRecords = ReadTimeLog(isoTimeLog, this.TaskDataPath); if (isoRecords != null) { isoRecords = isoRecords.ToList(); //Avoids multiple reads ISOTime time = isoTimeLog.GetTimeElement(this.TaskDataPath); //Identify unique devices represented in this TimeLog data IEnumerable <string> deviceElementIDs = time.DataLogValues.Where(d => d.ProcessDataDDI != "DFFF" && d.ProcessDataDDI != "DFFE").Select(d => d.DeviceElementIdRef); Dictionary <ISODevice, HashSet <string> > loggedDeviceElementsByDevice = new Dictionary <ISODevice, HashSet <string> >(); foreach (string deviceElementID in deviceElementIDs) { ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(deviceElementID); if (isoDeviceElement != null) { ISODevice device = isoDeviceElement.Device; if (!loggedDeviceElementsByDevice.ContainsKey(device)) { loggedDeviceElementsByDevice.Add(device, new HashSet <string>()); } loggedDeviceElementsByDevice[device].Add(deviceElementID); } } //Split all devices in the same TimeLog into separate OperationData objects to handle multi-implement scenarios //This will ensure implement geometries/DeviceElementUse Depths & Orders do not get confused between implements List <OperationData> operationDatas = new List <OperationData>(); foreach (ISODevice dvc in loggedDeviceElementsByDevice.Keys) { OperationData operationData = new OperationData(); //This line will necessarily invoke a spatial read in order to find //1)The correct number of CondensedWorkState working datas to create //2)Any Widths and Offsets stored in the spatial data IEnumerable <DeviceElementUse> sections = sectionMapper.Map(time, isoRecords, operationData.Id.ReferenceId, loggedDeviceElementsByDevice[dvc]); var workingDatas = sections != null?sections.SelectMany(x => x.GetWorkingDatas()).ToList() : new List <WorkingData>(); var sectionsSimple = sectionMapper.ConvertToBaseTypes(sections.ToList()); operationData.GetSpatialRecords = () => spatialMapper.Map(isoRecords, workingDatas); operationData.MaxDepth = sections.Count() > 0 ? sections.Select(s => s.Depth).Max() : 0; operationData.GetDeviceElementUses = x => x == 0 ? sectionsSimple : new List <DeviceElementUse>(); operationData.PrescriptionId = prescriptionID; operationData.OperationType = GetOperationTypeFromLoggingDevices(time); operationData.ProductId = GetProductIDForOperationData(loggedTask, dvc); operationData.SpatialRecordCount = isoRecords.Count(); operationDatas.Add(operationData); } return(operationDatas); } return(null); }
public EquipmentConfiguration ImportConnection(ISOTask task, ISOConnection isoConnection) { EquipmentConfiguration equipConfig = new EquipmentConfiguration(); StringBuilder descriptionBuilder = new StringBuilder(); //First Device Element int? connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoConnection.DeviceElementIdRef_0); Connector adaptConnector1 = null; if (connectorID.HasValue) { adaptConnector1 = DataModel.Catalog.Connectors.SingleOrDefault(d => d.Id.ReferenceId == connectorID.Value); if (adaptConnector1 != null) { equipConfig.Connector1Id = adaptConnector1.Id.ReferenceId; ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(isoConnection.DeviceElementIdRef_0); descriptionBuilder.Append(isoDeviceElement.Device.DeviceDesignator); descriptionBuilder.Append(":"); descriptionBuilder.Append(isoDeviceElement.DeviceElementDesignator); } } if (adaptConnector1 == null) { descriptionBuilder.Append("Unknown"); } descriptionBuilder.Append("<->"); //Second Device Element Connector adaptConnector2 = null; connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoConnection.DeviceElementIdRef_1); if (connectorID.HasValue) { adaptConnector2 = DataModel.Catalog.Connectors.SingleOrDefault(d => d.Id.ReferenceId == connectorID.Value); if (adaptConnector2 != null) { equipConfig.Connector2Id = adaptConnector2.Id.ReferenceId; ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(isoConnection.DeviceElementIdRef_1); descriptionBuilder.Append(isoDeviceElement.Device.DeviceDesignator); descriptionBuilder.Append(":"); descriptionBuilder.Append(isoDeviceElement.DeviceElementDesignator); } } if (adaptConnector2 == null) { descriptionBuilder.Append("Unknown"); } equipConfig.Description = descriptionBuilder.ToString(); return(equipConfig); }
private int GetHierarchyPosition(ISODeviceElement deviceElement) { int position = 0; while (deviceElement != null) { deviceElement = deviceElement.Parent as ISODeviceElement; position++; } return(position); }
public DeviceElementHierarchies(IEnumerable <ISODevice> devices, RepresentationMapper representationMapper) { Items = new Dictionary <string, DeviceElementHierarchy>(); foreach (ISODevice device in devices) { ISODeviceElement rootDeviceElement = device.DeviceElements.SingleOrDefault(det => det.DeviceElementType == ISODeviceElementType.Device); if (rootDeviceElement != null) { Items.Add(device.DeviceId, new DeviceElementHierarchy(rootDeviceElement, 0, representationMapper)); } } }
public EquipmentConfiguration ImportConnection(ISOTask task, ISOConnection isoConnection) { EquipmentConfiguration equipConfig = new EquipmentConfiguration(); StringBuilder descriptionBuilder = new StringBuilder(); //First Device Element int?connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoConnection.DeviceElementIdRef_0); if (connectorID.HasValue) { Connector adaptConnector1 = DataModel.Catalog.Connectors.Single(d => d.Id.ReferenceId == connectorID.Value); equipConfig.Connector1Id = adaptConnector1.Id.ReferenceId; ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(isoConnection.DeviceElementIdRef_0); descriptionBuilder.Append(isoDeviceElement.Device.DeviceDesignator); descriptionBuilder.Append(":"); descriptionBuilder.Append(isoDeviceElement.DeviceElementDesignator); } else { descriptionBuilder.Append("Unknown"); } descriptionBuilder.Append("<->"); //Second Device Element connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoConnection.DeviceElementIdRef_1); if (connectorID.HasValue) { Connector adaptConnector2 = DataModel.Catalog.Connectors.Single(d => d.Id.ReferenceId == connectorID.Value); equipConfig.Connector2Id = adaptConnector2.Id.ReferenceId; ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(isoConnection.DeviceElementIdRef_1); descriptionBuilder.Append(isoDeviceElement.Device.DeviceDesignator); descriptionBuilder.Append(":"); descriptionBuilder.Append(isoDeviceElement.DeviceElementDesignator); } else { descriptionBuilder.Append("Unknown"); } equipConfig.Description = descriptionBuilder.ToString(); //DataLogTriggers if (task.DataLogTriggers.Any()) { DataLogTriggerMapper dltMapper = new DataLogTriggerMapper(TaskDataMapper); dltMapper.ImportDataLogTriggers(task.DataLogTriggers); } return(equipConfig); }
private Dictionary <string, List <ISOProductAllocation> > GetProductAllocationsByDeviceElement(ISOTask loggedTask, ISODevice dvc) { Dictionary <string, List <ISOProductAllocation> > output = new Dictionary <string, List <ISOProductAllocation> >(); foreach (ISOProductAllocation pan in loggedTask.ProductAllocations.Where(p => !string.IsNullOrEmpty(p.DeviceElementIdRef))) { if (dvc.DeviceElements.Select(d => d.DeviceElementId).Contains(pan.DeviceElementIdRef)) //Filter PANs by this DVC { ISODeviceElement deviceElement = dvc.DeviceElements.First(d => d.DeviceElementId == pan.DeviceElementIdRef); AddProductAllocationsForDeviceElement(output, pan, deviceElement); } } return(output); }
private DeviceElementUse FindExistingDeviceElementUseForCondensedData(ISODeviceElement targetSection, List <DeviceElementUse> pendingDeviceElementUses) { DeviceElementUse existingDeviceElementUse = null; int?deviceElementID = TaskDataMapper.InstanceIDMap.GetADAPTID(targetSection.DeviceElementId); if (deviceElementID.HasValue) { DeviceElementConfiguration config = DataModel.Catalog.DeviceElementConfigurations.FirstOrDefault(d => d.DeviceElementId == deviceElementID.Value); if (config != null) { existingDeviceElementUse = pendingDeviceElementUses.FirstOrDefault(p => p.DeviceConfigurationId == config.Id.ReferenceId); } } return(existingDeviceElementUse); }
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); } } }
private void ExportConnectorElement(Connector adaptConnector, ISODeviceElement parentElement, List <ISODeviceElement> pendingDeviceElements, ref int objectID, ref int deviceElementNumber) { objectID++; deviceElementNumber++; ISODeviceElement isoDeviceElement = new ISODeviceElement(parentElement.Device); isoDeviceElement.DeviceElementId = adaptConnector.Id.FindIsoId() ?? GenerateId(); isoDeviceElement.DeviceElementDesignator = $"{parentElement.Device.DeviceDesignator}_Connector"; isoDeviceElement.DeviceElementType = ISODeviceElementType.Connector; isoDeviceElement.ParentObjectId = parentElement.DeviceElementObjectId; isoDeviceElement.DeviceElementNumber = (uint)deviceElementNumber; isoDeviceElement.DeviceElementObjectId = (uint)objectID; pendingDeviceElements.Add(isoDeviceElement); TaskDataMapper.InstanceIDMap.Add(adaptConnector.Id.ReferenceId, isoDeviceElement.DeviceElementId); }
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 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)); }
private void ExportDeviceProperty(ISODeviceElement deviceElement, NumericRepresentationValue representationValue, int objectID) { ISODeviceProperty dpt = new ISODeviceProperty(); dpt.ObjectID = (uint)objectID; switch (representationValue.Representation.Code) { case "0043": case "0046": dpt.DDI = representationValue.Representation.Code; dpt.Designator = "Width"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetInline": dpt.DDI = "0086"; dpt.Designator = "XOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetLateral": dpt.DDI = "0087"; dpt.Designator = "YOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetVertical": dpt.DDI = "0088"; dpt.Designator = "ZOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; } if (!string.IsNullOrEmpty(dpt.DDI)) { deviceElement.Device.DeviceProperties.Add(dpt); deviceElement.DeviceObjectReferences.Add(new ISODeviceObjectReference() { DeviceObjectId = (uint)objectID }); } }
/// <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); } } } } }
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 void AddProductAllocationsForDeviceElement(Dictionary <string, Dictionary <string, ISOProductAllocation> > productAllocations, ISOProductAllocation pan, ISODeviceElement deviceElement, string hierarchyPoistion) { if (!productAllocations.ContainsKey(deviceElement.DeviceElementId)) { productAllocations.Add(deviceElement.DeviceElementId, new Dictionary <string, ISOProductAllocation>()); } productAllocations[deviceElement.DeviceElementId][hierarchyPoistion] = pan; foreach (ISODeviceElement child in deviceElement.ChildDeviceElements) { AddProductAllocationsForDeviceElement(productAllocations, pan, child, hierarchyPoistion); } }
private void ExportDeviceProperties(ISODeviceElement isoDeviceElement, DeviceElement adaptDeviceElement) { //Connectors if (isoDeviceElement.ChildDeviceElements != null) { foreach (ISODeviceElement connectorElement in isoDeviceElement.ChildDeviceElements.Where(d => d.DeviceElementType == ISODeviceElementType.Connector)) { int?connectorID = TaskDataMapper.InstanceIDMap.GetADAPTID(connectorElement.DeviceElementId); if (connectorID.HasValue) { Connector connector = DataModel.Catalog.Connectors.First(c => c.Id.ReferenceId == connectorID.Value); HitchPoint hitch = DataModel.Catalog.HitchPoints.FirstOrDefault(h => h.Id.ReferenceId == connector.HitchPointId); if (hitch != null && hitch.ReferencePoint != null) { ExportDeviceProperty(connectorElement, hitch.ReferencePoint.XOffset, ++_devicePropertyObjectID); ExportDeviceProperty(connectorElement, hitch.ReferencePoint.YOffset, ++_devicePropertyObjectID); ExportDeviceProperty(connectorElement, hitch.ReferencePoint.ZOffset, ++_devicePropertyObjectID); } } } } //Device Element Widths & Offsets IEnumerable <DeviceElementConfiguration> configs = DataModel.Catalog.DeviceElementConfigurations.Where(c => c.DeviceElementId == adaptDeviceElement.Id.ReferenceId); foreach (DeviceElementConfiguration config in configs) { if (config is MachineConfiguration) { MachineConfiguration machineConfig = config as MachineConfiguration; ISODeviceElement navigationElement = isoDeviceElement.Device.DeviceElements.FirstOrDefault(d => d.DeviceElementType == ISODeviceElementType.Navigation); if (navigationElement == null) { if (machineConfig.GpsReceiverXOffset != null) { ExportDeviceProperty(navigationElement, machineConfig.GpsReceiverXOffset, ++_devicePropertyObjectID); } if (machineConfig.GpsReceiverYOffset != null) { ExportDeviceProperty(navigationElement, machineConfig.GpsReceiverYOffset, ++_devicePropertyObjectID); } if (machineConfig.GpsReceiverZOffset != null) { ExportDeviceProperty(navigationElement, machineConfig.GpsReceiverZOffset, ++_devicePropertyObjectID); } } } else if (config is ImplementConfiguration) { ImplementConfiguration implementConfig = config as ImplementConfiguration; if (implementConfig.Width != null) { ExportDeviceProperty(isoDeviceElement, implementConfig.Width, ++_devicePropertyObjectID); } if (implementConfig.Offsets != null) { implementConfig.Offsets.ForEach(o => ExportDeviceProperty(isoDeviceElement, o, ++_devicePropertyObjectID)); } } else if (config is SectionConfiguration) { SectionConfiguration sectionConfig = config as SectionConfiguration; if (sectionConfig.InlineOffset != null) { ExportDeviceProperty(isoDeviceElement, sectionConfig.InlineOffset, ++_devicePropertyObjectID); } if (sectionConfig.LateralOffset != null) { ExportDeviceProperty(isoDeviceElement, sectionConfig.LateralOffset, ++_devicePropertyObjectID); } if (sectionConfig.SectionWidth != null) { ExportDeviceProperty(isoDeviceElement, sectionConfig.SectionWidth, ++_devicePropertyObjectID); } } } }
private IEnumerable <OperationData> ImportTimeLog(ISOTask loggedTask, ISOTimeLog isoTimeLog, int?prescriptionID) { WorkingDataMapper workingDataMapper = new WorkingDataMapper(new EnumeratedMeterFactory(), TaskDataMapper); SectionMapper sectionMapper = new SectionMapper(workingDataMapper, TaskDataMapper); SpatialRecordMapper spatialMapper = new SpatialRecordMapper(new RepresentationValueInterpolator(), sectionMapper, workingDataMapper, TaskDataMapper); IEnumerable <ISOSpatialRow> isoRecords = ReadTimeLog(isoTimeLog, this.TaskDataPath); bool useDeferredExecution = false; if (isoRecords != null) { try { if (TaskDataMapper.Properties != null) { //Set this property to override the default behavior of pre-iterating the data bool.TryParse(TaskDataMapper.Properties.GetProperty("SpatialRecordDeferredExecution"), out useDeferredExecution); } if (!useDeferredExecution) { isoRecords = isoRecords.ToList(); //Avoids multiple reads } //Set a UTC "delta" from the first record where possible. We set only one per data import. if (!TaskDataMapper.GPSToLocalDelta.HasValue) { var firstRecord = isoRecords.FirstOrDefault(); if (firstRecord != null && firstRecord.GpsUtcDateTime.HasValue) { //Local - UTC = Delta. This value will be rough based on the accuracy of the clock settings but will expose the ability to derive the UTC times from the exported local times. TaskDataMapper.GPSToLocalDelta = (firstRecord.TimeStart - firstRecord.GpsUtcDateTime.Value).TotalHours; } } } catch (Exception ex) { TaskDataMapper.AddError($"Timelog file {isoTimeLog.Filename} is invalid. Skipping.", ex.Message, null, ex.StackTrace); return(null); } ISOTime time = isoTimeLog.GetTimeElement(this.TaskDataPath); //Identify unique devices represented in this TimeLog data IEnumerable <string> deviceElementIDs = time.DataLogValues.Where(d => d.ProcessDataDDI != "DFFF" && d.ProcessDataDDI != "DFFE").Select(d => d.DeviceElementIdRef); Dictionary <ISODevice, HashSet <string> > loggedDeviceElementsByDevice = new Dictionary <ISODevice, HashSet <string> >(); foreach (string deviceElementID in deviceElementIDs) { ISODeviceElement isoDeviceElement = TaskDataMapper.DeviceElementHierarchies.GetISODeviceElementFromID(deviceElementID); if (isoDeviceElement != null) { ISODevice device = isoDeviceElement.Device; if (!loggedDeviceElementsByDevice.ContainsKey(device)) { loggedDeviceElementsByDevice.Add(device, new HashSet <string>()); } loggedDeviceElementsByDevice[device].Add(deviceElementID); } } //Split all devices in the same TimeLog into separate OperationData objects to handle multi-implement scenarios //This will ensure implement geometries/DeviceElementUse Depths & Orders do not get confused between implements List <OperationData> operationDatas = new List <OperationData>(); foreach (ISODevice dvc in loggedDeviceElementsByDevice.Keys) { OperationData operationData = new OperationData(); //Determine products Dictionary <string, List <ISOProductAllocation> > productAllocations = GetProductAllocationsByDeviceElement(loggedTask, dvc); List <int> productIDs = GetDistinctProductIDs(TaskDataMapper, productAllocations); //This line will necessarily invoke a spatial read in order to find //1)The correct number of CondensedWorkState working datas to create //2)Any Widths and Offsets stored in the spatial data IEnumerable <DeviceElementUse> sections = sectionMapper.Map(time, isoRecords, operationData.Id.ReferenceId, loggedDeviceElementsByDevice[dvc], productAllocations); var workingDatas = sections != null?sections.SelectMany(x => x.GetWorkingDatas()).ToList() : new List <WorkingData>(); operationData.GetSpatialRecords = () => spatialMapper.Map(isoRecords, workingDatas, productAllocations); operationData.MaxDepth = sections.Count() > 0 ? sections.Select(s => s.Depth).Max() : 0; operationData.GetDeviceElementUses = x => sectionMapper.ConvertToBaseTypes(sections.Where(s => s.Depth == x).ToList()); operationData.PrescriptionId = prescriptionID; operationData.OperationType = GetOperationTypeFromLoggingDevices(time); operationData.ProductIds = productIDs; operationData.SpatialRecordCount = isoRecords.Count(); operationDatas.Add(operationData); } //Set the CoincidentOperationDataIds property identifying Operation Datas from the same TimeLog. operationDatas.ForEach(o => o.CoincidentOperationDataIds = operationDatas.Where(o2 => o2.Id.ReferenceId != o.Id.ReferenceId).Select(o3 => o3.Id.ReferenceId).ToList()); return(operationDatas); } return(null); }
private void AddProductAllocationsForDeviceElement(Dictionary <string, List <ISOProductAllocation> > productAllocations, ISOProductAllocation pan, ISODeviceElement deviceElement) { if (!productAllocations.ContainsKey(deviceElement.DeviceElementId)) { productAllocations.Add(deviceElement.DeviceElementId, new List <ISOProductAllocation>()); } productAllocations[deviceElement.DeviceElementId].Add(pan); foreach (ISODeviceElement child in deviceElement.ChildDeviceElements) { AddProductAllocationsForDeviceElement(productAllocations, pan, child); } }
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); }
public DeviceElementHierarchy(ISODeviceElement deviceElement, int depth, RepresentationMapper representationMapper, HashSet <int> crawledElements = null, DeviceElementHierarchy parent = null) { RepresentationMapper = representationMapper; //This Hashset will track that we don't build infinite hierarchies. //The plugin does not support peer control at this time. _crawledElements = crawledElements; if (_crawledElements == null) { _crawledElements = new HashSet <int>(); } if (_crawledElements.Add((int)deviceElement.DeviceElementObjectId)) { Type = deviceElement.DeviceElementType; DeviceElement = deviceElement; Depth = depth; Order = (int)deviceElement.DeviceElementNumber; //Using this number as analagous to this purpose. The ISO spec requires these numbers increment from left to right as in ADAPT. (See ISO11783-10:2015(E) B.3.2 Element number) //DeviceProperty assigned Widths & Offsets //DeviceProcessData assigned values will be assigned as the SectionMapper reads timelog data. //Width ISODeviceProperty widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0046"); if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0046"; } else { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0043"); if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0043"; } } //Offsets ISODeviceProperty xOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0086"); if (xOffsetProperty != null) { XOffset = xOffsetProperty.Value; } ISODeviceProperty yOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0087"); if (yOffsetProperty != null) { YOffset = yOffsetProperty.Value; } ISODeviceProperty zOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0088"); if (zOffsetProperty != null) { ZOffset = zOffsetProperty.Value; } //Children IEnumerable <ISODeviceElement> childDeviceElements = deviceElement.Device.DeviceElements.Where(det => det.ParentObjectId == deviceElement.DeviceElementObjectId);// && det.DeviceElementType == ISOEnumerations.ISODeviceElementType.Section); if (childDeviceElements.Any()) { int childDepth = depth + 1; Children = new List <DeviceElementHierarchy>(); foreach (ISODeviceElement det in childDeviceElements) { DeviceElementHierarchy child = new DeviceElementHierarchy(det, childDepth, representationMapper, _crawledElements, this); Children.Add(child); } } //Parent Parent = parent; } }
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); }
public DeviceHierarchyElement(ISODeviceElement deviceElement, int depth, RepresentationMapper representationMapper, bool mergeSingleBinsIntoBoom, Dictionary <string, List <string> > missingGeometryDefinitions, HashSet <int> crawledElements = null, DeviceHierarchyElement parent = null) { RepresentationMapper = representationMapper; MergedElements = new List <ISODeviceElement>(); //This Hashset will track that we don't build infinite hierarchies. //The plugin does not support peer control at this time. _crawledElements = crawledElements; if (_crawledElements == null) { _crawledElements = new HashSet <int>(); } if (_crawledElements.Add((int)deviceElement.DeviceElementObjectId)) { Type = deviceElement.DeviceElementType; DeviceElement = deviceElement; Depth = depth; Order = (int)deviceElement.DeviceElementNumber; //Using this number as analagous to this purpose. The ISO spec requires these numbers increment from left to right as in ADAPT. (See ISO11783-10:2015(E) B.3.2 Element number) //DeviceProperty assigned Widths & Offsets //DeviceProcessData assigned values will be assigned as the SectionMapper reads timelog data. //Width ISODeviceProperty widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0046"); //Max width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0046"; } else { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0044"); //Default working width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0044"; } if (widthProperty == null) { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0043"); //Actual working width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0043"; } } } if (Width == null) { //We are missing a width DPT. Log it (0046 as a substitute here for any valid width) for possible retrieval from the TLG binaries. AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0046"); } //Offsets ISODeviceProperty xOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0086"); if (xOffsetProperty != null) { XOffset = xOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0086"); } ISODeviceProperty yOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0087"); if (yOffsetProperty != null) { YOffset = yOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0087"); } ISODeviceProperty zOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0088"); if (zOffsetProperty != null) { ZOffset = zOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0088"); } //Children IEnumerable <ISODeviceElement> childDeviceElements = deviceElement.Device.DeviceElements.Where(det => det.ParentObjectId == deviceElement.DeviceElementObjectId && det.ParentObjectId != det.DeviceElementObjectId); //Do not create children for an element classified as its own parent if (childDeviceElements.Any()) { int childDepth = depth + 1; Children = new List <DeviceHierarchyElement>(); foreach (ISODeviceElement childDeviceElement in childDeviceElements) { //If there is a single bin child of the boom (usually alongside sections), //we can logically combine the bin and boom to have a clean hierarchy //where sections are the direct children of the element containing the rates. //We currently use an import property (MergeSingleBinsIntoBoom) to enable this functionality. //Note that if there are any duplicate DDIs on both the Bin and Boom (non-standard per Annex F.3), //the FirstOrDefault() logic in the setter methods in the SpatialRecordMapper will prefer the Boom and suppress the Bin data. if (mergeSingleBinsIntoBoom && (DeviceElement.DeviceElementType == ISODeviceElementType.Device || DeviceElement.DeviceElementType == ISODeviceElementType.Function) && childDeviceElement.DeviceElementType == ISODeviceElementType.Bin && childDeviceElements.Count(c => c.DeviceElementType == ISODeviceElementType.Bin) == 1) { //Set the element into the MergedElements list MergedElements.Add(childDeviceElement); //Set its children as children of the boom foreach (ISODeviceElement binChild in childDeviceElement.ChildDeviceElements.Where(det => det.ParentObjectId == childDeviceElement.DeviceElementObjectId && det.ParentObjectId != det.DeviceElementObjectId)) { Children.Add(new DeviceHierarchyElement(binChild, childDepth, representationMapper, mergeSingleBinsIntoBoom, missingGeometryDefinitions, _crawledElements, this)); } //This functionality will not work in the ADAPT framework today for multiple bins on one boom (i.e., ISO 11783-10:2015(E) F.23 & F.33). //For these, we will fall back to the more basic default functionality in HandleBinDeviceElements() //where we separate bins and sections into different depths within the ADAPT device hierarchy. //Plugin implementers will need to rationalize the separate bins to the single boom, //with the rate for each bin associated to the corresponding DeviceElement in the ADAPT model. //Were this multi-bin/single boom DDOP common, we could perhaps extend the WorkingData(?) class with some new piece of information //To differentiate like data elements from different bins and thereby extend the merge functionality to this case. } else { //Add the child device element DeviceHierarchyElement child = new DeviceHierarchyElement(childDeviceElement, childDepth, representationMapper, mergeSingleBinsIntoBoom, missingGeometryDefinitions, _crawledElements, this); Children.Add(child); } } } //Parent Parent = parent; } }
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 ISODeviceElement ExportDeviceElement(DeviceElement adaptDeviceElement, ISODevice isoDevice, List <ISODeviceElement> pendingDeviceElements, ref int objectID, ref int elementNumber) { ISODeviceElement det = new ISODeviceElement(isoDevice); objectID++; elementNumber++; //ID string id = adaptDeviceElement.Id.FindIsoId() ?? GenerateId(); det.DeviceElementId = id; ExportIDs(adaptDeviceElement.Id, id); //Object ID det.DeviceElementObjectId = (uint)objectID; //Device Element Number det.DeviceElementNumber = (uint)elementNumber; //Designator det.DeviceElementDesignator = adaptDeviceElement.Description; //Device Element Type switch (adaptDeviceElement.DeviceElementType) { case DeviceElementTypeEnum.Machine: case DeviceElementTypeEnum.Implement: det.DeviceElementType = ISODeviceElementType.Device; break; case DeviceElementTypeEnum.Bin: det.DeviceElementType = ISODeviceElementType.Bin; break; case DeviceElementTypeEnum.Function: det.DeviceElementType = ISODeviceElementType.Function; break; case DeviceElementTypeEnum.Section: det.DeviceElementType = ISODeviceElementType.Section; break; case DeviceElementTypeEnum.Unit: det.DeviceElementType = ISODeviceElementType.Unit; break; } //Parent ID DeviceElement parentDeviceElement = DataModel.Catalog.DeviceElements.FirstOrDefault(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); if (parentDeviceElement != null) { string deviceElementID = TaskDataMapper.InstanceIDMap.GetISOID(parentDeviceElement.Id.ReferenceId); if (pendingDeviceElements.Any(d => d.DeviceElementId == deviceElementID)) { det.ParentObjectId = pendingDeviceElements.First(d => d.DeviceElementId == deviceElementID).DeviceElementObjectId; } } else { DeviceModel parentDeviceModel = DataModel.Catalog.DeviceModels.FirstOrDefault(d => d.Id.ReferenceId == adaptDeviceElement.ParentDeviceId); if (parentDeviceModel != null) { //Parent is Device det.ParentObjectId = 0; } } //Add to the collection pendingDeviceElements.Add(det); //Child Elements int deviceElementNumber = 1; foreach (DeviceElement childElement in DataModel.Catalog.DeviceElements.Where(d => d.ParentDeviceId == adaptDeviceElement.Id.ReferenceId)) { ExportDeviceElement(childElement, isoDevice, pendingDeviceElements, ref objectID, ref deviceElementNumber); } //Connectors if (det.DeviceElementType == ISODeviceElementType.Device) { //Connectors should only exist as children of the top level DeviceElement foreach (DeviceElementConfiguration config in DataModel.Catalog.DeviceElementConfigurations.Where(c => c.DeviceElementId == adaptDeviceElement.Id.ReferenceId)) { foreach (Connector connector in DataModel.Catalog.Connectors.Where(c => c.DeviceElementConfigurationId == config.Id.ReferenceId)) { ExportConnectorElement(connector, det, pendingDeviceElements, ref objectID, ref deviceElementNumber); } } } //Device Properties ExportDeviceProperties(det, adaptDeviceElement); return(det); }
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; } } } }