/// <summary> /// Send devices lastKnownStatus to cws deviceGateway aka connected site /// Don't need to await as this process should be fire and forget /// We don't care if the post is valid, or device exists etc /// </summary> public void SendDeviceStatusToDeviceGateway(TagFileDetail tagFileDetail, TAGFilePreScan tagFilePreScan) { if (tagFilePreScan.PlatformType == CWSDeviceTypeEnum.EC520 || tagFilePreScan.PlatformType == CWSDeviceTypeEnum.EC520W || tagFilePreScan.PlatformType == CWSDeviceTypeEnum.Unknown) { _log.LogInformation($"#Progress# {nameof(SendDeviceStatusToDeviceGateway)} Not an applicable DeviceType: {tagFilePreScan.PlatformType}"); } else { var seedLatitude = MathUtilities.RadiansToDegrees(tagFilePreScan.SeedLatitude ?? 0.0); var seedLongitude = MathUtilities.RadiansToDegrees(tagFilePreScan.SeedLongitude ?? 0.0); var seedNorthing = tagFilePreScan.SeedNorthing; var seedEasting = tagFilePreScan.SeedEasting; if (Math.Abs(seedLatitude) < Consts.TOLERANCE_DECIMAL_DEGREE && Math.Abs(seedLongitude) < Consts.TOLERANCE_DECIMAL_DEGREE) { // This check is also done as a pre-check as the scenario is very frequent, to avoid the TFA API call overhead. var message = $"#Progress# {nameof(SendDeviceStatusToDeviceGateway)} tagfile: {tagFileDetail.tagFileName} doesn't have a valid Seed Lat/Long. {tagFilePreScan.SeedLatitude}/{tagFilePreScan.SeedLongitude}. "; if (seedNorthing != null && seedEasting != null) { message += $" It does have a Seed Northing/Easting {seedNorthing}/{seedEasting} however local grids are not currently supported for deviceGateway."; } _log.LogWarning(message); } else { var deviceLksModel = new DeviceLKSModel { TimeStamp = tagFilePreScan.SeedTimeUTC, Latitude = seedLatitude, Longitude = seedLongitude, Height = tagFilePreScan.SeedHeight, AssetSerialNumber = tagFilePreScan.HardwareID, AssetNickname = tagFilePreScan.MachineID, AppName = (tagFilePreScan.PlatformType == CWSDeviceTypeEnum.TMC) ? "TMC" : "GCS900", AppVersion = tagFilePreScan.ApplicationVersion, DesignName = tagFilePreScan.DesignName, // PlatformType is only passed as part of DeviceName {platformType}-{assetSerialNumber} AssetType = tagFilePreScan.MachineType.GetEnumMemberValue(), Devices = string.IsNullOrWhiteSpace(tagFilePreScan.RadioSerial) ? null : new List <ConnectedDevice> { new ConnectedDevice { Model = tagFilePreScan.RadioType, SerialNumber = tagFilePreScan.RadioSerial } } }; _log.LogInformation($"#Progress# {nameof(SendDeviceStatusToDeviceGateway)} Posting deviceLks to cws deviceGateway: {JsonConvert.SerializeObject(deviceLksModel)}"); var cwsDeviceGatewayClient = DIContext.Obtain <ICwsDeviceGatewayClient>(); var customHeaders = _tPaaSApplicationAuthentication.CustomHeaders(); _log.LogInformation($"#Progress# {nameof(SendDeviceStatusToDeviceGateway)} Got customHeaders"); // don't await this call, should be fire and forget cwsDeviceGatewayClient.CreateDeviceLKS($"{deviceLksModel.AssetType}-{deviceLksModel.AssetSerialNumber}", deviceLksModel, customHeaders) .ContinueWith((task) => { if (task.IsFaulted) { _log.LogError(task.Exception, $"#Progress# {nameof(SendDeviceStatusToDeviceGateway)}: Error Sending to Connected Site", null); } }, TaskContinuationOptions.OnlyOnFaulted); } _log.LogInformation($"#Progress# {nameof(SendDeviceStatusToDeviceGateway)} Post to ces deviceGateway completed"); } }
/// <summary> /// Execute the conversion operation on the TAG file, returning a boolean success result. /// Sets up local state detailing the pre-scan fields retrieved from the TAG file /// </summary> public bool ExecuteLegacyTAGFile(string filename, Stream tagData, Guid assetUid, bool isJohnDoe) { Log.LogInformation($"In {nameof(ExecuteLegacyTAGFile)}: reading file {filename} for asset {assetUid}, JohnDoe: {isJohnDoe}"); ReadResult = TAGReadResult.NoError; List <UTMCoordPointPair> aCSBladePositions = null; List <UTMCoordPointPair> ACSRearAxlePositions = null; List <UTMCoordPointPair> ACSTrackPositions = null; List <UTMCoordPointPair> ACSWheelPositions = null; try { Processor?.Dispose(); // Locate the machine in the local set of machines, adding one if necessary Machine = Machines.Locate(assetUid, isJohnDoe); var machineType = MachineType.Unknown; var machineHardwareId = string.Empty; var machineId = string.Empty; //Prescan to get all relevant information necessary for processing the tag file. e.g. Machinetype for swather, Type of coordinate system (ACS) var tagFilePreScan = new TAGFilePreScan(); tagFilePreScan.Execute(tagData); tagData.Position = 0; // reset if (tagFilePreScan.ReadResult == TAGReadResult.NoError) { machineType = tagFilePreScan.MachineType; // used in creation of swather machineHardwareId = tagFilePreScan.HardwareID; machineId = tagFilePreScan.MachineID; IsUTMCoordinateSystem = !tagFilePreScan.IsCSIBCoordSystemTypeOnly; // do we need to convert UTM coordinates to project coordinates if (IsUTMCoordinateSystem && tagFilePreScan.ProcessedEpochCount > 0) { Log.LogInformation($"{nameof(ExecuteLegacyTAGFile)}: ACS coordinate system detected. {filename}"); aCSBladePositions = new List <UTMCoordPointPair>(); ACSRearAxlePositions = new List <UTMCoordPointPair>(); ACSTrackPositions = new List <UTMCoordPointPair>(); ACSWheelPositions = new List <UTMCoordPointPair>(); if (!CollectAndConvertBladePostions(_targetSiteModel, ref tagData, ref aCSBladePositions, ref ACSRearAxlePositions, ref ACSTrackPositions, ref ACSWheelPositions)) { Log.LogError($"{nameof(ExecuteLegacyTAGFile)}: Failed to collect and convert blade positions for tagfile processing with ACS. TAG FILE:{filename}"); ReadResult = TAGReadResult.CoordinateConversionFailure; return(false); } } } else { Log.LogError($"Unsuccessful prescan of tagfile. {tagFilePreScan.ReadResult}"); return(false); } if (Machine == null) { // Now we know more about the machine have another go finding it Machine = Machines.Locate(assetUid, machineId, isJohnDoe); } if (Machine == null) { Log.LogDebug($"Creating new machine in common converter for AssetUid = {assetUid}, JohnDoe = {isJohnDoe}, machineId = {machineId}, machineHardwareId = {machineHardwareId}"); Machine = Machines.CreateNew(machineId, machineHardwareId, machineType, DeviceTypeEnum.MANUALDEVICE, isJohnDoe, assetUid); } if (Machine.MachineType == MachineType.Unknown && machineType != MachineType.Unknown) { Machine.MachineType = machineType; } var holdMachineType = Machine.MachineType; // Locate the aggregator, adding one if necessary var machineTargetValueChangesAggregator = MachinesTargetValueChangesAggregator[Machine.InternalSiteModelMachineIndex] as ProductionEventLists; if (machineTargetValueChangesAggregator == null) { machineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, Machine.InternalSiteModelMachineIndex); MachinesTargetValueChangesAggregator.Add(machineTargetValueChangesAggregator); } Processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, machineTargetValueChangesAggregator); // If ACS coordinate system populate converted UTM coordinates if (IsUTMCoordinateSystem && tagFilePreScan.ProcessedEpochCount > 0) { if (aCSBladePositions != null && aCSBladePositions.Count > 0) { Processor.ConvertedBladePositions.AddRange(aCSBladePositions); } if (ACSRearAxlePositions != null && ACSRearAxlePositions.Count > 0) { Processor.ConvertedRearAxlePositions.AddRange(ACSRearAxlePositions); } if (ACSTrackPositions != null && ACSTrackPositions.Count > 0) { Processor.ConvertedTrackPositions.AddRange(ACSTrackPositions); } if (ACSWheelPositions != null && ACSWheelPositions.Count > 0) { Processor.ConvertedWheelPositions.AddRange(ACSWheelPositions); } } var sink = new TAGValueSink(Processor); using (var reader = new TAGReader(tagData)) { var tagFile = new TAGFile(); ReadResult = tagFile.Read(reader, sink); // Notify the processor that all reading operations have completed for the file Processor.DoPostProcessFileAction(ReadResult == TAGReadResult.NoError); SetPublishedState(Processor); Machine.MachineType = holdMachineType; if (ReadResult != TAGReadResult.NoError) { return(false); } } } catch (Exception e) // make sure any exception is trapped to return correct response to caller { Log.LogError(e, "Exception occurred while converting a TAG file"); return(false); } return(true); }