diff --git a/AsbCloudApp/Services/IAnalyticsService.cs b/AsbCloudApp/Services/IAnalyticsService.cs index 06d24be1..6654ee68 100644 --- a/AsbCloudApp/Services/IAnalyticsService.cs +++ b/AsbCloudApp/Services/IAnalyticsService.cs @@ -14,6 +14,6 @@ namespace AsbCloudApp.Services DateTime begin = default, DateTime end = default); IEnumerable GetOperationsToInterval(int wellId, int intervalHoursTimestamp, int workBeginTimestamp); - TelemetryAnalysis GetDrillingAnalysis(IEnumerable dataSaubBases); + void SaveAnalytics(DataSaubBase dataSaub); } } diff --git a/AsbCloudInfrastructure/Services/AnalyticsService.cs b/AsbCloudInfrastructure/Services/AnalyticsService.cs index 6b12e3ea..31551b97 100644 --- a/AsbCloudInfrastructure/Services/AnalyticsService.cs +++ b/AsbCloudInfrastructure/Services/AnalyticsService.cs @@ -12,14 +12,17 @@ namespace AsbCloudInfrastructure.Services { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; + private readonly ISaubDataCache saubDataCache; private readonly CacheTable cacheOperations; private readonly OperationDetectorService operationDetectorService; private readonly IEnumerable operations; - public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb) + public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, + ISaubDataCache saubDataCache, CacheDb cacheDb) { this.db = db; this.telemetryService = telemetryService; + this.saubDataCache = saubDataCache; cacheOperations = cacheDb.GetCachedTable((AsbCloudDbContext)db); operations = cacheOperations.Select(c => true); operationDetectorService = new OperationDetectorService(operations); @@ -146,7 +149,36 @@ namespace AsbCloudInfrastructure.Services return operationsGroupedByInterval; } - public TelemetryAnalysis GetDrillingAnalysis(IEnumerable dataSaubBases) + public void SaveAnalytics(DataSaubBase dataSaub) + { + saubDataCache.AddData(dataSaub); + + if (saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry).Count() > 1) + { + var dataSaubs = saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry) + .OrderBy(d => d.Date); + + var telemetryAnalysis = GetDrillingAnalysis(dataSaubs); + + if (saubDataCache.CurrentAnalysis is null) + saubDataCache.CurrentAnalysis = telemetryAnalysis; + + if (saubDataCache.CurrentAnalysis.IdOperation == telemetryAnalysis.IdOperation) + { + saubDataCache.CurrentAnalysis.Duration += + telemetryAnalysis.Duration; + saubDataCache.CurrentAnalysis.OperationEndDepth = dataSaub.WellDepth; + } + else + { + db.TelemetryAnalysis.Add(saubDataCache.CurrentAnalysis); + saubDataCache.CurrentAnalysis = telemetryAnalysis; + saubDataCache.CurrentAnalysis.OperationStartDepth = dataSaub.WellDepth; + } + } + } + + private TelemetryAnalysis GetDrillingAnalysis(IEnumerable dataSaubBases) { var lastSaubDate = dataSaubBases.Last().Date; @@ -169,16 +201,16 @@ namespace AsbCloudInfrastructure.Services .Select(s => (Value: (double)s.HookWeight, (s.Date - dataSaubBases.First().Date).TotalSeconds)); - var wellDepthChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubWellDepths); - var bitPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBitDepths); - var blockPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBlockPositions); - var rotorSpeedChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubRotorSpeeds); - var pressureChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubPressures); - var hookWeightChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubHookWeights); + var wellDepthChangingIndex = new InterpolationLine(saubWellDepths).GetAForLinearFormula(); + var bitPositionChangingIndex = new InterpolationLine(saubBitDepths).GetAForLinearFormula(); + var blockPositionChangingIndex = new InterpolationLine(saubBlockPositions).GetAForLinearFormula(); + var rotorSpeedChangingIndex = new InterpolationLine(saubRotorSpeeds).GetAForLinearFormula(); + var pressureChangingIndex = new InterpolationLine(saubPressures).GetAForLinearFormula(); + var hookWeightChangingIndex = new InterpolationLine(saubHookWeights).GetAForLinearFormula(); - var IsBlockRising = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001); - var IsBlockGoesDown = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001); - var IsBlockStandsStill = LinearFunctionCalculator.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)); + var IsBlockRising = InterpolationLine.IsValueDecreases(blockPositionChangingIndex, -0.0001); + var IsBlockGoesDown = InterpolationLine.IsValueIncreases(blockPositionChangingIndex, 0.0001); + var IsBlockStandsStill = InterpolationLine.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)); var drillingAnalysis = new TelemetryAnalysis { @@ -187,19 +219,19 @@ namespace AsbCloudInfrastructure.Services Duration = (int)(dataSaubBases.Last().Date - dataSaubBases.ElementAt(dataSaubBases.Count() - 2).Date).TotalSeconds, OperationStartDepth = null, OperationEndDepth = null, - IsWellDepthDecreasing = LinearFunctionCalculator.IsValueGoesDown(wellDepthChangingIndex, -0.0001), - IsWellDepthIncreasing = LinearFunctionCalculator.IsValueGoesUp(wellDepthChangingIndex, 0.0001), - IsBitPositionDecreasing = LinearFunctionCalculator.IsValueGoesDown(bitPositionChangingIndex, -0.0001), - IsBitPositionIncreasing = LinearFunctionCalculator.IsValueGoesUp(bitPositionChangingIndex, 0.0001), - IsBitDepthLess20 = LinearFunctionCalculator.IsAverageLessThanBound(saubBitDepths, 20), - IsBlockPositionDecreasing = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001), - IsBlockPositionIncreasing = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001), - IsRotorSpeedLt3 = LinearFunctionCalculator.IsAverageLessThanBound(saubRotorSpeeds, 3), - IsRotorSpeedGt3 = LinearFunctionCalculator.IsAverageMoreThanBound(saubRotorSpeeds, 3), - IsPressureLt20 = LinearFunctionCalculator.IsAverageLessThanBound(saubPressures, 20), - IsPressureGt20 = LinearFunctionCalculator.IsAverageMoreThanBound(saubPressures, 20), - IsHookWeightNotChanges = LinearFunctionCalculator.IsValueNotChanges(hookWeightChangingIndex, (0.0001, -0.0001)), - IsHookWeightLt3 = LinearFunctionCalculator.IsAverageLessThanBound(saubHookWeights, 3), + IsWellDepthDecreasing = InterpolationLine.IsValueDecreases(wellDepthChangingIndex, -0.0001), + IsWellDepthIncreasing = InterpolationLine.IsValueIncreases(wellDepthChangingIndex, 0.0001), + IsBitPositionDecreasing = InterpolationLine.IsValueDecreases(bitPositionChangingIndex, -0.0001), + IsBitPositionIncreasing = InterpolationLine.IsValueIncreases(bitPositionChangingIndex, 0.0001), + IsBitDepthLess20 = InterpolationLine.IsAverageLessThanBound(saubBitDepths, 20), + IsBlockPositionDecreasing = InterpolationLine.IsValueDecreases(blockPositionChangingIndex, -0.0001), + IsBlockPositionIncreasing = InterpolationLine.IsValueIncreases(blockPositionChangingIndex, 0.0001), + IsRotorSpeedLt3 = InterpolationLine.IsAverageLessThanBound(saubRotorSpeeds, 3), + IsRotorSpeedGt3 = InterpolationLine.IsAverageMoreThanBound(saubRotorSpeeds, 3), + IsPressureLt20 = InterpolationLine.IsAverageLessThanBound(saubPressures, 20), + IsPressureGt20 = InterpolationLine.IsAverageMoreThanBound(saubPressures, 20), + IsHookWeightNotChanges = InterpolationLine.IsValueNotChanges(hookWeightChangingIndex, (0.0001, -0.0001)), + IsHookWeightLt3 = InterpolationLine.IsAverageLessThanBound(saubHookWeights, 3), IdOperation = 1 }; diff --git a/AsbCloudInfrastructure/Services/DataService.cs b/AsbCloudInfrastructure/Services/DataService.cs index daaa4366..03b432e7 100644 --- a/AsbCloudInfrastructure/Services/DataService.cs +++ b/AsbCloudInfrastructure/Services/DataService.cs @@ -99,31 +99,7 @@ namespace AsbCloudInfrastructure.Services dataSaub.IdTelemetry = telemetryId; db.DataSaubBases.Add(dataSaub); - saubDataCache.AddData(dataSaub); - - if (saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry).Count() > 1) - { - var dataSaubs = saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry) - .OrderBy(d => d.Date); - - var telemetryAnalysis = analyticsService.GetDrillingAnalysis(dataSaubs); - - if(saubDataCache.CurrentAnalysis is null) - saubDataCache.CurrentAnalysis = telemetryAnalysis; - - if (saubDataCache.CurrentAnalysis.IdOperation == telemetryAnalysis.IdOperation) - { - saubDataCache.CurrentAnalysis.Duration += - telemetryAnalysis.Duration; - saubDataCache.CurrentAnalysis.OperationEndDepth = item.WellDepth; - } - else - { - db.TelemetryAnalysis.Add(saubDataCache.CurrentAnalysis); - saubDataCache.CurrentAnalysis = telemetryAnalysis; - saubDataCache.CurrentAnalysis.OperationStartDepth = item.WellDepth; - } - } + analyticsService.SaveAnalytics(dataSaub); } db.SaveChanges(); diff --git a/AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs b/AsbCloudInfrastructure/Services/InterpolationLine.cs similarity index 56% rename from AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs rename to AsbCloudInfrastructure/Services/InterpolationLine.cs index 05b0a0c6..fc1443f4 100644 --- a/AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs +++ b/AsbCloudInfrastructure/Services/InterpolationLine.cs @@ -3,22 +3,38 @@ using System.Linq; namespace AsbCloudInfrastructure.Services { - public static class LinearFunctionCalculator + public class InterpolationLine { - public static double GetAForLinearFormula(IEnumerable<(double value, double timestamp)> rawData) - { - var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); + private readonly decimal xSum; + private readonly decimal ySum; + private readonly decimal xySum; + private readonly decimal x2Sum; + private readonly IEnumerable<(double value, double timestamp)> rawData = new List<(double value, double timestamp)>(); + public InterpolationLine(IEnumerable<(double value, double timestamp)> rawData) + { + var data = rawData.Select((d) => new + { + X = d.timestamp, + Y = d.value + }); + xSum = (decimal)data.Sum(d => d.X); + ySum = (decimal)data.Sum(d => d.Y); + xySum = (decimal)data.Sum(d => d.X * d.Y); + x2Sum = (decimal)data.Sum(d => d.X * d.X); + + this.rawData = rawData; + } + public double GetAForLinearFormula() + { var result = (xSum * ySum - rawData.Count() * xySum) / (xSum * xSum - rawData.Count() * x2Sum); return (double)result; } - public static double GetBForLinearFormula(IEnumerable<(double value, double timestamp)> rawData) + public double GetBForLinearFormula() { - var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); - var result = (xSum * xySum - x2Sum * ySum) / (xSum * xSum - rawData.Count() * x2Sum); @@ -29,10 +45,10 @@ namespace AsbCloudInfrastructure.Services (double upperBound, double lowerBound) bounds) => value < bounds.upperBound && value > bounds.lowerBound; - public static bool IsValueGoesUp(double value, double bound) => + public static bool IsValueIncreases(double value, double bound) => value > bound; - public static bool IsValueGoesDown(double value, double bound) => + public static bool IsValueDecreases(double value, double bound) => value < bound; public static bool IsAverageLessThanBound(IEnumerable<(double Value, double TotalSeconds)> values, @@ -42,21 +58,5 @@ namespace AsbCloudInfrastructure.Services public static bool IsAverageMoreThanBound(IEnumerable<(double Value, double TotalSeconds)> values, double bound) => (values.Sum(s => s.Value) / values.Count()) >= bound; - - private static (decimal xSum, decimal ySum, decimal xySum, decimal x2Sum) GetFormulaVariables( - IEnumerable<(double value, double timestamp)> rawData) - { - var data = rawData.Select((d) => new - { - X = d.timestamp, - Y = d.value - }); - var xSum = (decimal)data.Sum(d => d.X); - var ySum = (decimal)data.Sum(d => d.Y); - var xySum = (decimal)data.Sum(d => d.X * d.Y); - var x2Sum = (decimal)data.Sum(d => d.X * d.X); - - return (xSum, ySum, xySum, x2Sum); - } } }