public WorkingData ConvertToBaseType(WorkingData meter)
        {
            if (meter is ISOEnumeratedMeter)
            {
                var enumMeter = (ISOEnumeratedMeter)meter;
                var newMeter  = new EnumeratedWorkingData
                {
                    AppliedLatency     = enumMeter.AppliedLatency,
                    DeviceElementUseId = enumMeter.DeviceElementUseId,
                    ReportedLatency    = enumMeter.ReportedLatency,
                    Representation     = enumMeter.Representation,
                    ValueCodes         = enumMeter.ValueCodes,
                };
                newMeter.Id.ReferenceId = meter.Id.ReferenceId;
                newMeter.Id.UniqueIds   = meter.Id.UniqueIds;

                return(newMeter);
            }
            return(meter);
        }
Esempio n. 2
0
        private void SetEnumeratedMeterValue(ISOSpatialRow isoSpatialRow, EnumeratedWorkingData meter, SpatialRecord spatialRecord)
        {
            var isoDataLogValue = _workingDataMapper.DataLogValuesByWorkingDataID[meter.Id.ReferenceId];
            var isoValue        = isoSpatialRow.SpatialValues.FirstOrDefault(v =>
                                                                             v.DataLogValue.DeviceElementIdRef == isoDataLogValue.DeviceElementIdRef &&
                                                                             v.DataLogValue.ProcessDataDDI == isoDataLogValue.ProcessDataDDI);

            if (isoValue != null)
            {
                var isoEnumeratedMeter = meter as ISOEnumeratedMeter;
                var enumeratedValue    = isoEnumeratedMeter.GetEnumeratedValue(isoValue, isoEnumeratedMeter);
                spatialRecord.SetMeterValue(meter, enumeratedValue);
                _representationValueInterpolator.SetMostRecentMeterValue(meter, enumeratedValue);
            }
            else
            {
                var value = _representationValueInterpolator.Interpolate(meter) as EnumeratedValue;
                spatialRecord.SetMeterValue(meter, value);
            }
        }
        public void GivenDdiAndSpatialValueWithNotInstalledStateWhenGetValueForMeterThenPrescriptionNotUsedIsReturned()
        {
            var spatialValue = new SpatialValue
            {
                Dlv = new DLV
                {
                    A = "16F"
                },
                Value = 3
            };

            var meter = new EnumeratedWorkingData
            {
                DeviceElementUseId = 1
            };

            var result = new CondensedSectionOverrideStateMeterCreator(367).GetValueForMeter(spatialValue, meter);

            Assert.AreEqual(DefinedTypeEnumerationInstanceList.dtiPrescriptionNotUsed.ToModelEnumMember().Value, result.Value.Value);
        }
Esempio n. 4
0
        public EnumeratedValue GetValueForMeter(SpatialValue value, EnumeratedWorkingData meter)
        {
            if (Convert.ToInt32(value.Dlv.A, 16) != DDI)
            {
                return(null);
            }

            ApplicationDataModel.Representations.EnumerationMember enumMember = null;

            if (value.Value == 1)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiDrawbar.ToModelEnumMember();
            }
            else if (value.Value == 2)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiRearTwoPoint.ToModelEnumMember();
            }
            else if (value.Value == 3)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiThreePoint.ToModelEnumMember();
            }
            else if (value.Value == 7)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiRearPivotWagonHitch.ToModelEnumMember();
            }

            if (enumMember == null)
            {
                return(null);
            }

            return(new EnumeratedValue
            {
                Representation = meter.Representation as ApplicationDataModel.Representations.EnumeratedRepresentation,
                Value = enumMember,
                Code = enumMember.Code
            });
        }
Esempio n. 5
0
        public EnumeratedValue GetValueForMeter(SpatialValue value, EnumeratedWorkingData meter)
        {
            if (value == null)
            {
                return(null);
            }

            EnumerationMember enumMember;

            if ((int)value.Value == 0)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiPrscMasterManualOff.ToModelEnumMember();
            }
            else if ((int)value.Value == 1)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiPrscMasterAutoOn.ToModelEnumMember();
            }
            else if ((int)value.Value == 2)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiPrscMasterError.ToModelEnumMember();
            }
            else if ((int)value.Value == 3)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiPrscMasterUndefined.ToModelEnumMember();
            }
            else
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiPrscMasterError.ToModelEnumMember();
            }

            return(new EnumeratedValue
            {
                Representation = meter.Representation as EnumeratedRepresentation,
                Value = enumMember,
                Code = enumMember.Code
            });
        }
Esempio n. 6
0
        public EnumeratedValue GetValueForMeter(SpatialValue value, EnumeratedWorkingData meter)
        {
            if (Convert.ToInt32(value.Dlv.A, 16) != DDI)
            {
                return(null);
            }

            ApplicationDataModel.Representations.EnumerationMember enumMember = DefinedTypeEnumerationInstanceList.dtiSCMasterUndefined.ToModelEnumMember();

            var reservedBitsMask  = 0x00000003;
            var valueLowerTwoBits = (int)value.Value & reservedBitsMask;

            if (valueLowerTwoBits == 0)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiSCMasterManualOff.ToModelEnumMember();
            }
            else if (valueLowerTwoBits == 1)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiSCMasterAutoOn.ToModelEnumMember();
            }
            else if (valueLowerTwoBits == 2)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiSCMasterError.ToModelEnumMember();
            }
            else if (valueLowerTwoBits == 3)
            {
                enumMember = DefinedTypeEnumerationInstanceList.dtiSCMasterUndefined.ToModelEnumMember();
            }

            return(new EnumeratedValue
            {
                Representation = meter.Representation as ApplicationDataModel.Representations.EnumeratedRepresentation,
                Value = enumMember,
                Code = enumMember.Code
            });
        }
        public static void DescribeSpatialData(Catalog catalog, LoggedData loggedData)
        {
            //Coincident Operations
            DescribeCoincidentOperations(loggedData);

            Console.WriteLine();
            Console.WriteLine("-----------------------");
            Console.WriteLine("Spatial Data");
            Console.WriteLine("-----------------------");
            Console.WriteLine();

            foreach (OperationData operationData in loggedData.OperationData)
            {
                //1.  Create some collections for tracking high-level/header information on the implement devices and sensors.
                List <WorkingData>    operationDataWorkingDatas       = new List <WorkingData>();
                Dictionary <int, int> useToDeviceConfigurationMapping = new Dictionary <int, int>();

                //ADAPT models spatial data in multiple depths according to a virtual hierarchy describing the data as it relates to the physical layout of the implement.
                //In the 2020 implementation,
                //  depth 0 refers to a single device representing the entire width of the implement and any sensors reporting data across the implement.
                //  depth 1 generally refers to row-by-row data, where multiple DeviceElements representing individual rows contain one or more sensors
                //  depth 2 is present on planting data where there are multiple varieties configured in specific parts of the implement.  In that case
                //depth 1 contains a description of the varieties
                //depth 2 contains the row-level data
                for (int depth = 0; depth <= operationData.MaxDepth; depth++)  //MaxDepth defines the maximum depth of data on an OperationData
                {
                    //A DeviceElementUse is an instance of a DeviceElement/DeviceElementConfiguration within a specific OperationData.
                    //It contains the collection of all data elements (WorkingData objects) reported on that DeviceElement during the Operation.
                    IEnumerable <DeviceElementUse> deviceElementUses = operationData.GetDeviceElementUses(depth);
                    foreach (DeviceElementUse deviceElementUse in deviceElementUses)
                    {
                        //Track the DeviceConfiguration that this DeviceElementUse relates to for reconciling data values to implement offsets for precise location
                        useToDeviceConfigurationMapping.Add(deviceElementUse.Id.ReferenceId, deviceElementUse.DeviceConfigurationId);

                        //A WorkingData is essentially a Sensor.   It is the definition of some object that will report data per spatial point.
                        //List all such sensors on this DeviceElementUse within this Operation
                        IEnumerable <WorkingData> workingDatas = deviceElementUse.GetWorkingDatas();

                        //Track these in the comprehensive list
                        operationDataWorkingDatas.AddRange(workingDatas);
                    }
                }

                //2. Illustrate any multivariety data present here.
                //If an OperationData from the 2020 plugin contains a maxdepth of 2, then level 1 describes parts of the planter with specific varieties
                if (operationData.OperationType == OperationTypeEnum.SowingAndPlanting &&
                    operationData.MaxDepth == 2)
                {
                    //------------------
                    //Split Planter data
                    //-------------------
                    Console.WriteLine($"OperationData {operationData.Id.ReferenceId} is planter data containing multiple varieties assigned to specific rows:");
                    IEnumerable <DeviceElementUse> levelOneDeviceElementUses = operationData.GetDeviceElementUses(1);
                    foreach (DeviceElementUse use in levelOneDeviceElementUses)
                    {
                        //Retrieve the DeviceElementConfiguration object that matches the DeviceElementUse on this specific operation
                        DeviceElementConfiguration deviceElementConfig = catalog.DeviceElementConfigurations.First(d => d.Id.ReferenceId == use.DeviceConfigurationId);

                        //We've named the Level 1 device elements with the varieties in this situation
                        Console.WriteLine(deviceElementConfig.Description);

                        //All rows planting that variety will be children of this device element,
                        //and the level 1 DeviceElementUse will have a WorkingData called "vrProductIndex" that will map to the variety
                    }
                    Console.WriteLine();
                }
                else if (operationData.OperationType == OperationTypeEnum.SowingAndPlanting &&
                         operationData.MaxDepth == 1 &&
                         operationDataWorkingDatas.Select(w => w.Representation.Code).Any(c => c == "vrProductIndex"))
                {
                    //------------------------------------------------------
                    //vSetSelect & mSet data (variable multi-hybrid planting)
                    //------------------------------------------------------
                    Console.WriteLine($"OperationData {operationData.Id.ReferenceId} is planter data containing multiple varieties dynamically assigned to each row.");

                    //Make a dictionary of product names
                    Dictionary <int, string> productNames = new Dictionary <int, string>();
                    foreach (int productID in operationData.ProductIds)
                    {
                        List <DeviceElementUse> productDeviceElementUses = new List <DeviceElementUse>();
                        Product product = catalog.Products.First(p => p.Id.ReferenceId == productID);
                        productNames.Add(productID, product.Description);
                    }

                    Console.WriteLine($"The following varieties are planted at various points in the field: {string.Join(", ", productNames.Values)}");

                    SpatialRecord firstPoint = operationData.GetSpatialRecords().First();
                    Console.WriteLine("For example, on the first point...");

                    //Examine the content of each DeviceElementUse at the row level with a product index working data
                    foreach (DeviceElementUse deviceElementUse in operationData.GetDeviceElementUses(1)) //1 is the row level where OperationData.MaxDepth == 1.
                    {
                        foreach (WorkingData productIndexWorkingData in deviceElementUse.GetWorkingDatas().Where(w => w.Representation.Code == "vrProductIndex"))
                        {
                            NumericRepresentationValue productValue = firstPoint.GetMeterValue(productIndexWorkingData) as NumericRepresentationValue;
                            int productIndex = (int)productValue.Value.Value;
                            DeviceElementConfiguration deviceElementConfiguration = catalog.DeviceElementConfigurations.First(d => d.Id.ReferenceId == deviceElementUse.DeviceConfigurationId);
                            Console.WriteLine($"{deviceElementConfiguration.Description} planted {productNames[productIndex]}.");
                        }
                    }

                    Console.WriteLine();
                }


                //3. Read the point-by-point data
                //With the data definition of the OperationData now in-hand, we can iterate the collection of physical points on the field to read the data.
                //Rather than writing out each data value to the screen, we will assemble them into collections to summarize after iterating all data
                Dictionary <WorkingData, List <object> > operationSpatialDataValues = new Dictionary <WorkingData, List <object> >();
                Dictionary <WorkingData, string>         numericDataUnitsOfMeasure  = new Dictionary <WorkingData, string>();

                //Similarly, we will track the geospatial envelope of the data to illustrate lat/lon data present
                double maxLat = Double.MinValue;
                double minLat = Double.MaxValue;
                double maxLon = Double.MinValue;
                double minLon = Double.MaxValue;

                Console.WriteLine("Reading point-by-point data...");
                Console.WriteLine();

                //IMPORTANT
                //To effectively manage memory usage, avoid invoking the iterator multiple times or iterate the entire list in a Linq expression.
                //The linq expressions below do not necessarily take this advice as the focus here is illustrative.
                foreach (SpatialRecord spatialRecord in operationData.GetSpatialRecords())
                {
                    //2020 data will always be in point form
                    Point point = spatialRecord.Geometry as Point;

                    //Track the lat/lon to illustrate the envelope of the dataset
                    double latitude  = point.Y;
                    double longitude = point.X;
                    if (latitude < minLat)
                    {
                        minLat = latitude;
                    }
                    if (latitude > maxLat)
                    {
                        maxLat = latitude;
                    }
                    if (longitude < minLon)
                    {
                        minLon = longitude;
                    }
                    if (longitude > maxLon)
                    {
                        maxLon = longitude;
                    }

                    //Examine the actual data on the points
                    foreach (WorkingData operationWorkingData in operationDataWorkingDatas)
                    {
                        //Create a List for data values on the first encounter with this WorkingData
                        if (!operationSpatialDataValues.ContainsKey(operationWorkingData))
                        {
                            operationSpatialDataValues.Add(operationWorkingData, new List <object>());
                        }

                        //---------------
                        //Representations
                        //---------------
                        //ADAPT publishes standard representations that often equate to ISO11783-11 Data Dictionary Identifiers (DDIs)
                        //These representations define a common type of agricultural measurement.
                        //Where Precision Planting has implemented representations that are not published with ADAPT, they are marked as UserDefined
                        //and the Name describes what each is.

                        //--------------------
                        //RepresentationValues
                        //--------------------
                        //A Representation Value is a complex type that allows the value to
                        //be augmented the full representation, the unit of measure and other data.

                        RepresentationValue representationValue = spatialRecord.GetMeterValue(operationWorkingData);

                        //Values reported may be of type Numeric or Enumerated
                        if (representationValue is NumericRepresentationValue)
                        {
                            NumericRepresentationValue numericRepresentationValue = representationValue as NumericRepresentationValue;
                            operationSpatialDataValues[operationWorkingData].Add(numericRepresentationValue.Value.Value); //Value is a double

                            //--------------------
                            //Units of Measure
                            //--------------------
                            //Store the UOM on the first encounter
                            if (!numericDataUnitsOfMeasure.ContainsKey(operationWorkingData))
                            {
                                numericDataUnitsOfMeasure.Add(operationWorkingData, numericRepresentationValue.Value.UnitOfMeasure.Code);

                                //ADAPT units of measure are documented in the Resources/UnitSystem.xml that is installed in any ADAPT project
                                //They take the form of unitCode[postive exponent]unitcode[negative exponent]
                                //Where the exponents allow for complex units.   E.g.s,
                                //lb = pounds
                                //ac = acres
                                //lb1ac-1 = pounds per acre
                                //mm3m-2 = cubic millimeters per square meter
                            }
                        }
                        else if (representationValue is EnumeratedValue)
                        {
                            EnumeratedValue enumeratedValue = representationValue as EnumeratedValue;
                            operationSpatialDataValues[operationWorkingData].Add(enumeratedValue.Value.Value); //Value is a string
                        }
                    }
                }

                Console.WriteLine();
                Console.WriteLine("-----------------------");
                Console.WriteLine($"{Enum.GetName(typeof(OperationTypeEnum), operationData.OperationType)} data");
                Console.WriteLine("-----------------------");
                Console.WriteLine();

                Console.WriteLine($"Data logged within envelope bounded by {minLat},{minLon} and {maxLat},{maxLon}.");
                Console.WriteLine();

                foreach (WorkingData workingData in operationSpatialDataValues.Keys)
                {
                    //We can obtain a reference to the part of the machine that logged the data via the DeviceConfigurationId property.
                    DeviceElementConfiguration deviceElementConfig = catalog.DeviceElementConfigurations.FirstOrDefault(d => d.Id.ReferenceId == useToDeviceConfigurationMapping[workingData.DeviceElementUseId]);
                    string deviceElementName = deviceElementConfig.Description;

                    if (operationSpatialDataValues[workingData].Any())
                    {
                        if (workingData is NumericWorkingData)
                        {
                            double max     = operationSpatialDataValues[workingData].Cast <double>().Max();
                            double average = operationSpatialDataValues[workingData].Cast <double>().Average();
                            double min     = operationSpatialDataValues[workingData].Cast <double>().Min();
                            string uom     = numericDataUnitsOfMeasure[workingData];
                            Console.WriteLine($"Numeric Working Data {deviceElementConfig.Description}-{workingData.Representation.Description} had a minimum value of {min}, and average of {average} and a maximum value of {max} {uom}.");
                            Console.WriteLine();
                        }
                        else if (workingData is EnumeratedWorkingData)
                        {
                            EnumeratedWorkingData    enumeratedWorkingData    = workingData as EnumeratedWorkingData;
                            EnumeratedRepresentation enumeratedRepresentation = enumeratedWorkingData.Representation as EnumeratedRepresentation;
                            IEnumerable <string>     enumerationValues        = enumeratedRepresentation.EnumeratedMembers.Select(e => e.Value);

                            foreach (string enumerationValue in enumerationValues)
                            {
                                int count = operationSpatialDataValues[workingData].Cast <string>().Count(v => v == enumerationValue);
                                Console.WriteLine($"Enumerated Working Data {deviceElementConfig.Description}-{workingData.Representation.Description} had {count} values of {enumerationValue}.");
                                Console.WriteLine();
                            }
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        public List <Feature> MapMultiple(OperationData operation, IEnumerable <SpatialRecord> spatialRecords)
        {
            List <DeviceElementUse> deviceElementUses = GetAllSections(operation);
            List <WorkingData>      workingDatas      = deviceElementUses.SelectMany(x => x.GetWorkingDatas()).ToList();    // meters

            // Display representaitons for debug
            Console.WriteLine($"Contains the following representations: ");
            foreach (var workingData in workingDatas)
            {
                Console.WriteLine($"{workingData.Representation.CodeSource}: {workingData.Representation.Code}");
            }
            Console.WriteLine($"");

            // inspired by ISOv4Plugin/Mappers/TimeLogMapper
            List <Feature> features = new List <Feature>();

            foreach (SpatialRecord spatialRecord in spatialRecords)
            {
                if (spatialRecord.Geometry != null && spatialRecord.Geometry as Point != null)
                {
                    Dictionary <string, object> properties = new Dictionary <string, object>();

                    Point location = spatialRecord.Geometry as Point;
                    if (location.X == 0 || location.Y == 0)
                    {
                        continue;
                    }

                    // altitude
                    if (location.Z != null)
                    {
                        properties.Add("Elevation", location.Z);
                    }

                    // timeStamp
                    properties.Add("Timestamp", spatialRecord.Timestamp.ToString());

                    // meter values
                    var workingDatasWithValues = workingDatas.Where(x => spatialRecord.GetMeterValue(x) != null);
                    foreach (WorkingData workingData in workingDatasWithValues)                                 //.Where(d => _dlvOrdersByWorkingDataID.ContainsKey(d.Id.ReferenceId)))
                    {
                        string key   = workingData.Representation.Code;
                        object value = null;
                        string uom   = null;

                        if (workingData is EnumeratedWorkingData)
                        {
                            EnumeratedWorkingData enumeratedMeter = workingData as EnumeratedWorkingData;
                            if (enumeratedMeter != null && spatialRecord.GetMeterValue(enumeratedMeter) != null)
                            {
                                EnumeratedValue enumValue = (spatialRecord.GetMeterValue(enumeratedMeter) as EnumeratedValue);
                                value = enumValue.Value.Value.ToString();
                            }
                        }
                        else if (workingData is NumericWorkingData)
                        {
                            NumericWorkingData numericMeter = workingData as NumericWorkingData;
                            if (numericMeter != null && spatialRecord.GetMeterValue(numericMeter) != null)
                            {
                                NumericRepresentationValue numValue = spatialRecord.GetMeterValue(numericMeter) as NumericRepresentationValue;
                                value = numValue.Value.Value;
                                uom   = numValue.Value.UnitOfMeasure.Code;

                                // better key for DDI (hex2int)
                                if (workingData.Representation.CodeSource == RepresentationCodeSourceEnum.ISO11783_DDI)
                                {
                                    if (numValue.Designator != null && numValue.Designator != "")
                                    {
                                        key = numValue.Designator;
                                    }
                                    else if (workingData.Representation.Description != null && workingData.Representation.Description != "")
                                    {
                                        key = workingData.Representation.Description;
                                    }
                                    else
                                    {
                                        // ILaR cause: key missing in representation system
                                        int intKey = int.Parse(key, System.Globalization.NumberStyles.HexNumber);
                                        if (_missingDDI.ContainsKey(intKey))
                                        {
                                            key = _missingDDI[intKey];
                                        }
                                        else
                                        {
                                            key = "DDI_" + intKey.ToString();
                                        }
                                    }
                                }
                            }
                        }
                        else // needed ?
                        {
                            value = spatialRecord.GetMeterValue(workingData);
                        }

                        if (value != null && key != null)
                        {
                            properties.Add(key, value);

                            if (uom != null)
                            {
                                properties.Add(key + "_Uom", uom);
                            }
                        }
                    }
                    // add to FC
                    features.Add(new Feature(PointMapper.MapPoint2Point(spatialRecord.Geometry as Point, _properties.AffineTransformation), properties));
                }
            }

            return(features);
        }