public void GivenTskWhenMapThenOperationDataAreMapped() { const string taskName = "TSK5"; var existingLoggedData = new LoggedData(); existingLoggedData.Id.UniqueIds.Add(new UniqueId { IdType = IdTypeEnum.String, Id = taskName, Source = UniqueIdMapper.IsoSource }); _documents.LoggedData = new List <LoggedData> { existingLoggedData }; var tlgs = new List <TLG> { new TLG() }; _tsk.Items = tlgs.ToArray(); _tsk.A = taskName; var operationDatas = new List <OperationData>(); _operationDataMapper.Setup(x => x.Map(tlgs, null, _dataPath, It.IsAny <int>(), _linkIds)).Returns(operationDatas); var result = MapSingle(); Assert.AreSame(operationDatas, result.OperationData); }
private static void AreEqual(LoggedData loggedData, TSK tsk, Catalog catalog, string cardPath) { var grower = catalog.Growers.SingleOrDefault(x => x.Id.ReferenceId == loggedData.GrowerId); var farm = catalog.Farms.SingleOrDefault(x => x.Id.ReferenceId == loggedData.FarmId); var field = catalog.Fields.SingleOrDefault(x => x.Id.ReferenceId == loggedData.FieldId); if (grower != null) { Assert.AreEqual(grower.Id.FindIsoId(), tsk.C); } if (farm != null) { Assert.AreEqual(farm.Id.FindIsoId(), tsk.D); } if (field != null) { Assert.AreEqual(field.Id.FindIsoId(), tsk.E); } if (loggedData.TimeScopes != null && loggedData.TimeScopes.Any()) { var tims = tsk.Items.Where(x => x.GetType() == typeof(TIM)).Cast <TIM>().ToList(); TimAssert.AreEqual(loggedData.TimeScopes, tims); } if (loggedData.OperationData != null && loggedData.OperationData.Any()) { var tlgs = tsk.Items.Where(x => x.GetType() == typeof(TLG)).Cast <TLG>().ToList(); TlgAssert.AreEqual(loggedData.OperationData.ToList(), tlgs, catalog, cardPath); } }
private LoggedData LoadTask(XmlNode inputNode) { var task = new LoggedData(); // Required fields. Do not proceed if they are missing var taskId = inputNode.GetXmlNodeValue("@A"); if (taskId == null) { return(null); } // Optional fields task.Description = inputNode.GetXmlNodeValue("@B"); LoadField(inputNode.GetXmlNodeValue("@E"), task); LoadFarm(inputNode.GetXmlNodeValue("@D"), task); LoadCustomer(inputNode.GetXmlNodeValue("@C"), task); LoadGuidanceAllocations(inputNode, task); LoadCommentAllocations(inputNode, task); task.Id.UniqueIds.Add(new UniqueId { Id = taskId, Source = UniqueIdMapper.IsoSource, IdType = IdTypeEnum.String, }); _taskDocument.LoadLinkedIds(taskId, task.Id); return(task); }
protected override void DoWhenAllDataIsReady() { LoggedData.Add(Provider.Data); //Timestamps.Add(Timestamps.LastOrDefault() + Provider.Interval); Timestamps.Add(Provider.RunTime); Intervals.Add(Provider.Interval); }
protected override void DoWhenAllDataIsReady() { //if (Res.DebuggingSignalFlag) // Log.Debug(_tag, $"DoWhenAll: {LoggedData.Count} data pts."); if (AllowDataUpdates) //base.DoWhenAllDataIsReady(); { LoggedData.Add(Provider.Data); //Timestamps.Add(Timestamps.LastOrDefault() + Provider.Interval); Timestamps.Add(Provider.RunTime + AccumulatedRuntime); Intervals.Add(Provider.Interval); } //if (SessionCTS != null && SessionCTS.IsCancellationRequested) //{ // if (DeactivationCounter == 0) // { // SessionCTS = null; // DeactivationCounter = 10; // AdditionalPointsSignal.Set(); // } // else DeactivationCounter--; //} if (InitialInterval == TimeSpan.Zero) { InitialInterval = Provider.Interval; } }
public static void DescribeSummaryData(ApplicationDataModel adm, LoggedData loggedData) { Console.WriteLine(); Console.WriteLine("-----------------------"); Console.WriteLine("Task Summary Information"); Console.WriteLine("-----------------------"); Console.WriteLine(); //Each LoggedData object will map to a Summary object via the SummaryId property. Summary summary = adm.Documents.Summaries.SingleOrDefault(s => s.Id.ReferenceId == loggedData.SummaryId); if (summary != null) { //Each summary will have a start date timescope TimeScope timeScope = summary.TimeScopes.SingleOrDefault(t => t.DateContext == DateContextEnum.ActualStart); DateTime startTime = timeScope.TimeStamp1.Value; //In the 2020 Plugin, we include the end date as TimeStamp2. DateTime endTime = timeScope.TimeStamp2.Value; Console.WriteLine($"The field operation started at {startTime.ToString()} and ended at {endTime.ToString()}"); Console.WriteLine(); Console.WriteLine($"The following are totals/averages for the field operation:"); //The 2020 plugin will summarize all field Operation data into a single StampedMetersValues collection. //The ADAPT framework allows for multiple StampedMetersValues in cases where multiple timestamps govern multiple data values foreach (MeteredValue meteredValue in summary.SummaryData.Single().Values) { NumericRepresentationValue representationValue = meteredValue.Value as NumericRepresentationValue; string summaryValueName = representationValue.Representation.Description; string uomCode = representationValue.Value.UnitOfMeasure.Code; double value = representationValue.Value.Value; Console.WriteLine($"{summaryValueName}: {value} {uomCode}"); } Console.WriteLine(); //For seed and liquid fertilizer products, the Plugin will summarize data by product Console.WriteLine($"The following are totals/averages by product:"); foreach (OperationSummary operationSummary in summary.OperationSummaries) { Product product = adm.Catalog.Products.FirstOrDefault(p => p.Id.ReferenceId == operationSummary.ProductId); Console.WriteLine($"{product.Description}:"); foreach (MeteredValue meteredValue in operationSummary.Data.Single().Values) { NumericRepresentationValue representationValue = meteredValue.Value as NumericRepresentationValue; string summaryValueName = representationValue.Representation.Description; string uomCode = representationValue.Value.UnitOfMeasure.Code; double value = representationValue.Value.Value; Console.WriteLine($"{summaryValueName}: {value} {uomCode}"); } Console.WriteLine(); } } }
private void LoadGuidanceAllocations(XmlNode inputNode, LoggedData task) { var allocations = GuidanceAllocationLoader.Load(inputNode, _taskDocument); _taskDocument.GuidanceAllocations.AddRange(allocations); task.GuidanceAllocationIds = allocations.Select(x => x.Id.ReferenceId).ToList(); }
private void LoadCustomer(string customerId, LoggedData task) { var customer = _taskDocument.Customers.FindById(customerId); if (customer != null) { task.GrowerId = customer.Id.ReferenceId; } }
private void LoadFarm(string farmId, LoggedData task) { var farm = _taskDocument.Farms.FindById(farmId); if (farm != null) { task.FarmId = farm.Id.ReferenceId; task.GrowerId = farm.GrowerId; } }
private void LoadField(string fieldId, LoggedData task) { var field = _taskDocument.Fields.FindById(fieldId); if (field != null) { task.FieldId = field.Id.ReferenceId; task.FarmId = field.FarmId; } }
public IEnumerable <LoggedData> ImportLoggedDatas(IEnumerable <ISOTask> isoLoggedTasks) { List <LoggedData> adaptLoggedDatas = new List <LoggedData>(); foreach (ISOTask isoLoggedTask in isoLoggedTasks) { LoggedData loggedData = ImportLoggedData(isoLoggedTask); adaptLoggedDatas.Add(loggedData); } return(adaptLoggedDatas); }
protected override void DoWhenAllDataIsReady() { LoggedData.Add(new Datapoint <T1, T2>() { Value1 = (providers[0] as IProvider <T1>).Data, Value2 = (providers[1] as IProvider <T2>).Data }); //if (LoggedData.All(d => d.Magnitude() < 1e-10) && LoggedData.Count > 5) throw new Exception("Caught another zero list of data... WHY???"); //Timestamps.Add(Timestamps.LastOrDefault() + providers[0].Interval); Timestamps.Add(providers[0].RunTime); Intervals.Add(providers[0].Interval); }
private Summary ImportSummary(ISOTask isoLoggedTask, LoggedData loggedData) { //Per ISO11783-10:2015(E) 6.8.3, the last Time element contains the comprehensive task totals. //Earlier Time elements contain the task totals leading up to points where the Task was paused. //As such, the Summary.TimeScopes will include detail on various intermittent Timescopes, //and the Summary.SummaryData will contain totals from only the last time element. //Summary.SummaryData.Stamp will be set to a comprehensive time stamp from the beginning of the first time to the end of the last. Summary summary = null; IEnumerable <ISOTime> timeElements = isoLoggedTask.Times.Where(t => t.HasStart && t.HasType); if (timeElements.Any()) { summary = new Summary(); //TimeScopes summary.TimeScopes = new List <TimeScope>(); foreach (ISOTime time in isoLoggedTask.Times.Where(t => t.HasStart && t.HasType)) //Nothing added without a Start and Type attribute { TimeScope timeScope = new TimeScope(); timeScope.TimeStamp1 = time.Start; if (time.Stop != null) { timeScope.TimeStamp2 = time.Stop; } if (time.Stop == null && time.Duration != null) { //Calculate the Stop time if missing and duration present timeScope.TimeStamp2 = timeScope.TimeStamp1.Value.AddSeconds(time.Duration.Value); } timeScope.DateContext = time.Type == ISOEnumerations.ISOTimeType.Planned ? DateContextEnum.ProposedStart : DateContextEnum.ActualStart; timeScope.Duration = timeScope.TimeStamp2.GetValueOrDefault() - timeScope.TimeStamp1.GetValueOrDefault(); summary.TimeScopes.Add(timeScope); } //Summary Data - does not have a product reference summary.SummaryData = ImportSummaryData(timeElements); //Operation Summaries - includes a product reference summary.OperationSummaries = ImportOperationSummaries(isoLoggedTask); //Copy properties from LoggedData summary.GrowerId = loggedData.GrowerId; summary.FarmId = loggedData.FarmId; summary.FieldId = loggedData.FieldId; summary.CropZoneId = loggedData.CropZoneId; summary.PersonRoleIds = loggedData.PersonRoleIds; summary.WorkItemIds = loggedData.WorkItemIds; summary.GuidanceAllocationIds = loggedData.GuidanceAllocationIds; summary.EquipmentConfigurationGroup = loggedData.EquipmentConfigurationGroup; } return(summary); }
public static void GetLoggedData(Catalog catalog, LoggedData loggedData) { Console.WriteLine("Logged Data: " + loggedData.Description); // Write out the grower/farm/field Grower grower = catalog.Growers.Find(x => x.Id.ReferenceId == loggedData.GrowerId); if (grower != null) { Console.WriteLine("Grower: " + grower.Name); } Farm farm = catalog.Farms.Find(x => x.Id.ReferenceId == loggedData.FarmId); if (farm != null) { Console.WriteLine("Farm: " + farm.Description); } Field field = catalog.Fields.Find(x => x.Id.ReferenceId == loggedData.FieldId); if (field != null) { Console.WriteLine("Field: " + field.Description); } foreach (OperationData opData in loggedData.OperationData) { Console.WriteLine("Operation: " + opData.OperationType); switch (opData.OperationType) { case OperationTypeEnum.Harvesting: GetHarvestData(opData, catalog); break; case OperationTypeEnum.SowingAndPlanting: GetPlantingData(opData, catalog); break; case OperationTypeEnum.CropProtection: case OperationTypeEnum.Fertilizing: GetAsAppliedData(opData, catalog); break; } } // Clean up loggedData.ReleaseSpatialData(); Console.WriteLine(); }
public void Setup() { _loggedData = new LoggedData(); _loggedDatas = new List <LoggedData> { _loggedData }; _catalog = new Catalog(); _datacardPath = ""; _taskDocumentWriter = new TaskDocumentWriter(); _timeMapperMock = new Mock <ITimeMapper>(); _tlgMapperMock = new Mock <ITlgMapper>(); _taskMapper = new TaskMapper(_timeMapperMock.Object, _tlgMapperMock.Object); }
public void GivenTskWithNullItemWhenMapThenPrescriptionIdIsNullToOperationMapper() { var existingLoggedData = new LoggedData(); existingLoggedData.Id.UniqueIds.Add(new UniqueId { IdType = IdTypeEnum.String, Id = "TSK0", Source = UniqueIdMapper.IsoSource }); _documents.LoggedData = new List <LoggedData> { existingLoggedData }; _tsk.A = "TSK0"; MapSingle(); _operationDataMapper.Verify(x => x.Map(It.IsAny <List <TLG> >(), null, _dataPath, existingLoggedData.Id.ReferenceId, _linkIds), Times.Once); }
public void readLog() { StreamReader sr = new StreamReader("LogFile.txt"); string readData = String.Empty; LoggedData.Clear(); while (sr.EndOfStream != true) { readData = sr.ReadLine(); if (readData != null) { LoggedData.Add(readData); } } sr.Close(); }
public async Task ShouldUseOnlyLogDataForFieldForOperationTotals() { var extraLogData = new LoggedData { FieldId = 324234, OperationData = new List <OperationData> { new OperationData() } }; _dataModel.Documents.LoggedData = _dataModel.Documents.LoggedData.Concat(extraLogData); var operationTotals = await _operationTotalsCalculator.Calculate(_field, _dataModel); Assert.AreEqual(3, operationTotals.Length); }
public static void DescribeCoincidentOperations(LoggedData loggedData) { Console.WriteLine(); Console.WriteLine("-----------------------"); Console.WriteLine("Coincident Operations"); Console.WriteLine("-----------------------"); Console.WriteLine(); //The OperationData.CoincidentOperationDataIDs property contains a reference to all related OperationData objects that represent //parallel operations, logged at the same place and time. //E.g., a planter may have the capability to plant seed, apply a granular insecticide and a liquid fertilizer all in one pass. //This example would be represented as 3 OperationDatas coincident to one another. //In such case, an implementer may wish to iterate the collections in parallel or otherwise join the data. List <List <int> > coincidentGroupings = new List <List <int> >(); foreach (OperationData operationData in loggedData.OperationData) { if (operationData.CoincidentOperationDataIds.Any()) { List <int> coincidentList = new List <int>() { operationData.Id.ReferenceId }; //Add the id for the given item operationData.CoincidentOperationDataIds.ForEach(i => coincidentList.Add(i)); if (!coincidentGroupings.Any(g => g.Contains(operationData.Id.ReferenceId))) { coincidentGroupings.Add(coincidentList); } } } if (coincidentGroupings.Any()) { Console.WriteLine($"The following operations are coincident to one another."); foreach (List <int> grouping in coincidentGroupings) { Console.WriteLine(string.Join(",", grouping.ToArray())); } } else { Console.WriteLine($"There were no coincident operations."); } }
public void ClearDataOlderThan(TimeSpan span) { if (Timestamps.Count == 0) { return; } var currentTimestamp = Timestamps.Last(); var numToSkip = Timestamps.FindIndex(t => t + span >= currentTimestamp); //Log.Debug(_tag, $"At {currentTimestamp}, clearing out {numToSkip} data points, keeping as of {Timestamps.Skip(numToSkip).First()}."); //Provider.Deactivate(); AllowDataUpdates = false; LoggedData = LoggedData.Skip(numToSkip).ToList(); Intervals = Intervals.Skip(numToSkip).ToList(); Timestamps = Timestamps.Skip(numToSkip).ToList(); AllowDataUpdates = true; //Provider.Activate(); }
private IWriter[] MapItems(LoggedData loggedData, string datacardPath, TaskDocumentWriter taskDocumentWriter) { var times = FindAndMapTimes(loggedData.TimeScopes); var tlgs = _tlgMapper.Map(loggedData.OperationData, datacardPath, taskDocumentWriter); var items = new List <IWriter>(); if (times != null) { items.AddRange(times); } if (tlgs != null) { items.AddRange(tlgs); } return(items.ToArray()); }
private TSK Map(LoggedData loggedData, Catalog catalog, string taskDataPath, int taskNumber, TaskDocumentWriter taskDocumentWriter) { var taskId = "TSK" + taskNumber; taskDocumentWriter.Ids.Add(taskId, loggedData.Id); var tsk = new TSK { A = taskId, B = loggedData.Description, C = FindGrowerId(loggedData.GrowerId, catalog), D = FindFarmId(loggedData.FarmId, catalog), E = FindFieldId(loggedData.FieldId, catalog), G = TSKG.Item4, Items = MapItems(loggedData, taskDataPath, taskDocumentWriter) }; return(tsk); }
public void GivenTskWithGrdWhenMapThenPrescriptionIdFromCatalogIsPassedToOperationMapper() { var prescription = new RasterGridPrescription(); prescription.Id.UniqueIds = new List <UniqueId> { new UniqueId { IdType = IdTypeEnum.String, Id = "FIX1", Source = "http://dictionary.isobus.net/isobus/" } }; _catalog.Prescriptions = new List <Prescription> { prescription }; var existingLoggedData = new LoggedData(); existingLoggedData.Id.UniqueIds.Add(new UniqueId { IdType = IdTypeEnum.String, Id = "FIX1", Source = UniqueIdMapper.IsoSource }); _documents.LoggedData = new List <LoggedData> { existingLoggedData }; var grd = new GRD(); _tsk.Items = new List <IWriter> { grd }.ToArray(); _tsk.A = "FIX1"; MapSingle(); _operationDataMapper.Verify(x => x.Map(It.IsAny <List <TLG> >(), prescription.Id.ReferenceId, _dataPath, existingLoggedData.Id.ReferenceId, _linkIds), Times.Once); }
public async Task AddLoggedData(string deviceName, string data) { int?loggingDeviceId = await db.LoggingDevices .Where(dbLoggingDevice => dbLoggingDevice.DeviceName == deviceName) .Select(dbLoggingDevice => (int?)dbLoggingDevice.Id) .SingleOrDefaultAsync(); if (!loggingDeviceId.HasValue) { // Can't find the device. throw new DeviceNotFoundException(deviceName); } // Create the logged data and save it. LoggedData loggedData = new LoggedData { Data = data, LoggedTime = DateTime.UtcNow, LoggingDeviceId = loggingDeviceId.Value }; db.LoggedData.Add(loggedData); await db.SaveChangesAsync(); }
public void ClearData() { LoggedData.Clear(); Intervals.Clear(); Timestamps.Clear(); }
protected override T toImplicitType() { return(LoggedData.LastOrDefault()); }
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(); } } } } } }
protected override Datapoint <T1, T2> toImplicitType() { return(LoggedData.LastOrDefault()); }
private ISOTask Export(LoggedData loggedData) { ISOTask task = null; //Try to map to a pre-existing Work Item task where appropriate if (loggedData.OperationData.All(o => o.PrescriptionId.HasValue) && loggedData.OperationData.Select(o => o.PrescriptionId.Value).Distinct().Count() == 1) { int rxID = loggedData.OperationData.First().PrescriptionId.Value; if (_taskIDsByPrescription.ContainsKey(rxID)) { task = ISOTaskData.ChildElements.OfType <ISOTask>().FirstOrDefault(t => t.TaskID == _taskIDsByPrescription[rxID]); } } if (task == null) { task = new ISOTask(); //Task ID string taskID = loggedData.Id.FindIsoId() ?? GenerateId(); task.TaskID = taskID; } if (!ExportIDs(loggedData.Id, task.TaskID)) { //Update the mapping to represent the completed task TaskDataMapper.InstanceIDMap.ReplaceADAPTID(task.TaskID, loggedData.Id.ReferenceId); } //Task Designator task.TaskDesignator = loggedData.Description; //Customer Ref if (loggedData.GrowerId.HasValue) { task.CustomerIdRef = TaskDataMapper.InstanceIDMap.GetISOID(loggedData.GrowerId.Value); } //Farm Ref if (loggedData.FarmId.HasValue) { task.FarmIdRef = TaskDataMapper.InstanceIDMap.GetISOID(loggedData.FarmId.Value); } //Partfield Ref if (loggedData.CropZoneId.HasValue) { task.PartFieldIdRef = TaskDataMapper.InstanceIDMap.GetISOID(loggedData.CropZoneId.Value); } else if (loggedData.FieldId.HasValue) { task.PartFieldIdRef = TaskDataMapper.InstanceIDMap.GetISOID(loggedData.FieldId.Value); } //Status task.TaskStatus = ISOEnumerations.ISOTaskStatus.Completed; if (loggedData.OperationData.Any()) { //Time Logs task.TimeLogs = TimeLogMapper.ExportTimeLogs(loggedData.OperationData, TaskDataPath).ToList(); //Connections IEnumerable <int> taskEquipmentConfigIDs = loggedData.OperationData.SelectMany(o => o.EquipmentConfigurationIds); if (taskEquipmentConfigIDs.Any()) { IEnumerable <EquipmentConfiguration> taskEquipmentConfigs = DataModel.Catalog.EquipmentConfigurations.Where(d => taskEquipmentConfigIDs.Contains(d.Id.ReferenceId)); task.Connections = ConnectionMapper.ExportConnections(loggedData.Id.ReferenceId, taskEquipmentConfigs).ToList(); } } //Summaries if (loggedData.SummaryId.HasValue) { Summary summary = DataModel.Documents.Summaries.FirstOrDefault(s => s.Id.ReferenceId == loggedData.SummaryId.Value); if (summary != null) { task.Times.AddRange(ExportSummary(summary)); } List <ISOProductAllocation> productAllocations = GetProductAllocationsForSummary(summary); if (productAllocations != null) { task.ProductAllocations.AddRange(productAllocations); } } //Comments if (loggedData.Notes.Any()) { CommentAllocationMapper canMapper = new CommentAllocationMapper(TaskDataMapper); task.CommentAllocations = canMapper.ExportCommentAllocations(loggedData.Notes).ToList(); } //Worker Allocations if (loggedData.PersonRoleIds.Any()) { WorkerAllocationMapper workerAllocationMapper = new WorkerAllocationMapper(TaskDataMapper); List <PersonRole> personRoles = new List <PersonRole>(); foreach (int id in loggedData.PersonRoleIds) { PersonRole personRole = DataModel.Catalog.PersonRoles.FirstOrDefault(p => p.Id.ReferenceId == id); if (personRole != null) { personRoles.Add(personRole); } } task.WorkerAllocations = workerAllocationMapper.ExportWorkerAllocations(personRoles).ToList(); } //Guidance Allocations if (loggedData.GuidanceAllocationIds.Any()) { GuidanceAllocationMapper guidanceAllocationMapper = new GuidanceAllocationMapper(TaskDataMapper); List <GuidanceAllocation> allocations = new List <GuidanceAllocation>(); foreach (int id in loggedData.GuidanceAllocationIds) { GuidanceAllocation allocation = DataModel.Documents.GuidanceAllocations.FirstOrDefault(p => p.Id.ReferenceId == id); if (allocation != null) { allocations.Add(allocation); } } task.GuidanceAllocations = guidanceAllocationMapper.ExportGuidanceAllocations(allocations).ToList(); } return(task); }
private LoggedData ImportLoggedData(ISOTask isoLoggedTask) { LoggedData loggedData = new LoggedData(); loggedData.OperationData = new List <OperationData>(); //Task ID if (!ImportIDs(loggedData.Id, isoLoggedTask.TaskID)) { //In the case where a TSK contains both TZN and TLG data, we'll store the LoggedData as the mapped Task. //The Prescription ID will be assigned to the OperationData objects by means of the dictionary in this class. TaskDataMapper.InstanceIDMap.ReplaceADAPTID(isoLoggedTask.TaskID, loggedData.Id.ReferenceId); } //Task Name loggedData.Description = isoLoggedTask.TaskDesignator; //Grower ID loggedData.GrowerId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoLoggedTask.CustomerIdRef); //Farm ID loggedData.FarmId = TaskDataMapper.InstanceIDMap.GetADAPTID(isoLoggedTask.FarmIdRef); //Field ID int?pfdID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoLoggedTask.PartFieldIdRef); if (pfdID.HasValue) { if (DataModel.Catalog.CropZones.Any(c => c.Id.ReferenceId == pfdID.Value)) { loggedData.CropZoneId = pfdID.Value; } else { loggedData.FieldId = pfdID.Value; if (DataModel.Catalog.CropZones.Count(c => c.FieldId == pfdID) == 1) { //There is a single cropZone for the field. loggedData.CropZoneId = DataModel.Catalog.CropZones.Single(c => c.FieldId == pfdID).Id.ReferenceId; } } } //Responsible Worker if (!string.IsNullOrEmpty(isoLoggedTask.ResponsibleWorkerIdRef)) { ISOWorker worker = ISOTaskData.ChildElements.OfType <ISOWorker>().FirstOrDefault(w => w.WorkerId == isoLoggedTask.ResponsibleWorkerIdRef); int? personID = TaskDataMapper.InstanceIDMap.GetADAPTID(isoLoggedTask.ResponsibleWorkerIdRef); if (personID.HasValue) { //Create a Role PersonRole role = new PersonRole() { PersonId = personID.Value }; //Add to Catalog DataModel.Catalog.PersonRoles.Add(role); if (loggedData.PersonRoleIds == null) { loggedData.PersonRoleIds = new List <int>(); } //Add to Task loggedData.PersonRoleIds.Add(role.Id.ReferenceId); } } //Worker Allocations if (isoLoggedTask.WorkerAllocations.Any()) { WorkerAllocationMapper wanMapper = new WorkerAllocationMapper(TaskDataMapper); List <PersonRole> personRoles = wanMapper.ImportWorkerAllocations(isoLoggedTask.WorkerAllocations).ToList(); //Add to Catalog DataModel.Catalog.PersonRoles.AddRange(personRoles); if (loggedData.PersonRoleIds == null) { loggedData.PersonRoleIds = new List <int>(); } //Add to Task loggedData.PersonRoleIds.AddRange(personRoles.Select(p => p.Id.ReferenceId)); } //Guidance Allocations if (isoLoggedTask.GuidanceAllocations.Any()) { GuidanceAllocationMapper ganMapper = new GuidanceAllocationMapper(TaskDataMapper); List <GuidanceAllocation> allocations = ganMapper.ImportGuidanceAllocations(isoLoggedTask.GuidanceAllocations).ToList(); //Add to Catalog List <GuidanceAllocation> guidanceAllocations = DataModel.Documents.GuidanceAllocations as List <GuidanceAllocation>; if (guidanceAllocations != null) { guidanceAllocations.AddRange(allocations); } //Add to Task if (loggedData.GuidanceAllocationIds == null) { loggedData.GuidanceAllocationIds = new List <int>(); } loggedData.GuidanceAllocationIds.AddRange(allocations.Select(p => p.Id.ReferenceId)); } //Comments if (isoLoggedTask.CommentAllocations.Any()) { CommentAllocationMapper canMapper = new CommentAllocationMapper(TaskDataMapper); loggedData.Notes = canMapper.ImportCommentAllocations(isoLoggedTask.CommentAllocations).ToList(); } //Summaries if (isoLoggedTask.Times.Any(t => t.HasStart && t.HasType)) //Nothing added without a Start & Type attribute { //An ADAPT LoggedData has exactly one summary. This is what necessitates that ISO Task maps to LoggedData and ISO TimeLog maps to one or more Operation Data objects Summary summary = ImportSummary(isoLoggedTask, loggedData); if (DataModel.Documents.Summaries == null) { DataModel.Documents.Summaries = new List <Summary>(); } (DataModel.Documents.Summaries as List <Summary>).Add(summary); loggedData.SummaryId = summary.Id.ReferenceId; } //Operation Data if (isoLoggedTask.TimeLogs.Any()) { //Find ID for any Prescription that may also be tied to this task int?rxID = null; if (_rxIDsByTask.ContainsKey(isoLoggedTask.TaskID)) { rxID = _rxIDsByTask[isoLoggedTask.TaskID]; } loggedData.OperationData = TimeLogMapper.ImportTimeLogs(isoLoggedTask, rxID); } //Connections if (isoLoggedTask.Connections.Any()) { IEnumerable <EquipmentConfiguration> equipConfigs = ConnectionMapper.ImportConnections(isoLoggedTask); loggedData.EquipmentConfigurationGroup = new EquipmentConfigurationGroup(); loggedData.EquipmentConfigurationGroup.EquipmentConfigurations = equipConfigs.ToList(); //Make a reference to the IDs on the OperationData foreach (OperationData operationData in loggedData.OperationData) { operationData.EquipmentConfigurationIds.AddRange(equipConfigs.Select(e => e.Id.ReferenceId)); } DataModel.Catalog.EquipmentConfigurations.AddRange(equipConfigs); } return(loggedData); }