protected 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 = true; if (isoRecords != null) { try { if (TaskDataMapper.Properties == null || !bool.TryParse(TaskDataMapper.Properties.GetProperty(TaskDataMapper.SpatialRecordDeferredExecution), out useDeferredExecution)) { //Set this property to override the default behavior of deferring execution on the spatial data //We historically pre-iterated this data, giving certain benefits but having negative memory impacts //Going forward the default is to defer execution useDeferredExecution = true; } 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 = GetTimeElementFromTimeLog(isoTimeLog); //Identify unique devices represented in this TimeLog data IEnumerable <string> deviceElementIDs = time.DataLogValues.Where(d => !d.ProcessDataDDI.EqualsIgnoreCase("DFFF") && !d.ProcessDataDDI.EqualsIgnoreCase("DFFE")) .Select(d => d.DeviceElementIdRef).Distinct().ToList(); 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; if (!useDeferredExecution) { operationData.SpatialRecordCount = isoRecords.Count(); //We will leave this at 0 unless a consumer has overridden deferred execution of spatial data iteration } 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); }
public IEnumerable <ISODeviceElement> ExportDeviceElements(IEnumerable <DeviceElement> adaptRootDeviceElements, ISODevice isoDevice) { List <ISODeviceElement> isoDeviceElements = new List <ISODeviceElement>(); DeviceElement rootElement = null; if (adaptRootDeviceElements.Count() == 1) { rootElement = adaptRootDeviceElements.Single(); } else { //Create a single root device element to align with the ISO requirement rootElement = new DeviceElement(); rootElement.Description = isoDevice.DeviceDesignator; List <DeviceElement> clonedRootElements = new List <DeviceElement>(); foreach (DeviceElement element in adaptRootDeviceElements) { DeviceElement clone = new DeviceElement(); clone.BrandId = element.BrandId; clone.ContextItems = element.ContextItems; clone.Description = element.Description; clone.DeviceClassification = element.DeviceClassification; clone.DeviceElementType = element.DeviceElementType; clone.DeviceModelId = element.DeviceModelId; clone.Id.ReferenceId = element.Id.ReferenceId; clone.Id.UniqueIds = element.Id.UniqueIds; clone.ManufacturerId = element.ManufacturerId; clone.ParentDeviceId = rootElement.Id.ReferenceId; //Assign the clone to the new single root clone.SerialNumber = element.SerialNumber; clone.SeriesId = element.SeriesId; } } int objectID = 1; int deviceElementNumber = 1; ExportDeviceElement(rootElement, isoDevice, isoDeviceElements, ref objectID, ref deviceElementNumber); return(isoDeviceElements); }
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); ExportContextItems(adaptDeviceElement.ContextItems, id, "ADAPT_Context_Items:DeviceElement"); //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); }
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.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) { 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); }