示例#1
0
            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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        private int GetHierarchyPosition(ISODeviceElement deviceElement)
        {
            int position = 0;

            while (deviceElement != null)
            {
                deviceElement = deviceElement.Parent as ISODeviceElement;
                position++;
            }
            return(position);
        }
示例#6
0
 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));
         }
     }
 }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#10
0
        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);
        }
示例#13
0
        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);
        }
示例#17
0
        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);
                    }
                }
            }
        }
示例#19
0
        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);
        }
示例#20
0
        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);
            }
        }
示例#21
0
        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;
            }
        }
示例#23
0
        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;
            }
        }
示例#25
0
        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);
        }
示例#27
0
        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;
                    }
                }
            }
        }