From 62384b5673eb827a5599fbea75e39cdfb81e7168 Mon Sep 17 00:00:00 2001
From: eugeniy_ivanov <ea.ivanov@digitaldrilling.ru>
Date: Mon, 15 Aug 2022 01:17:00 +0500
Subject: [PATCH] =?UTF-8?q?-=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20?=
 =?UTF-8?q?=D1=84=D0=BE=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=81=D0=B5=D1=80?=
 =?UTF-8?q?=D0=B2=D0=B8=D1=81=20-=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?=
 =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20?=
 =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0?=
 =?UTF-8?q?=20=D0=B2=20Data=20Spin=20=D1=84=D0=BE=D0=BD=D0=BE=D0=B2=D0=BE?=
 =?UTF-8?q?=D0=B3=D0=BE=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D0=B0=20-?=
 =?UTF-8?q?=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=B8=D1=80=D0=BE?=
 =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9?=
 =?UTF-8?q?=20(=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF?=
 =?UTF-8?q?=D1=80=D0=BE=D0=B1=D0=B5=D0=BB=D0=BE=D0=B2=20=D0=B8=20=D0=BB?=
 =?UTF-8?q?=D0=B8=D1=88=D0=BD=D0=B8=D1=85=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8?=
 =?UTF-8?q?=D0=BE=D1=82=D0=B5=D0=BA)=20-=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?=
 =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?=
 =?UTF-8?q?=D1=85=20=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=B8=D1=8E=20=D0=BE=20=D0=BF=D0=BE=D0=B4=D1=81=D0=B8?=
 =?UTF-8?q?=D1=81=D1=82=D0=B5=D0=BC=D0=B0=D1=85=20(=D1=87=D0=B5=D1=80?=
 =?UTF-8?q?=D0=B5=D0=B7=20Entity=20Filler)=20-=20=D0=B2=20=D0=BC=D0=B5?=
 =?UTF-8?q?=D1=82=D0=BE=D0=B4=D0=B5=20Convert=20=D0=B2=20SubsystemOperatio?=
 =?UTF-8?q?nTimeService=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=B0=20?=
 =?UTF-8?q?=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=B8=D1=80=D0=BE?=
 =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=B4=D0=B0=D1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 AsbCloudApp/Data/Subsystems/SubsystemDto.cs   |   8 +-
 .../Subsystems/SubsystemOperationTimeDto.cs   |  18 +--
 .../Data/Subsystems/SubsystemStatDto.cs       |   8 +-
 .../Subsystems/SubsystemsSpinWithDepthDto.cs  |  30 ++++
 AsbCloudDb/Model/DefaultData/DefaultData.cs   |   1 +
 .../DefaultData/EntityFillerSubsystem.cs      |  24 ++++
 ...SubsystemOperationTimeBackgroundService.cs | 134 +++++++++++-------
 .../SubsystemOperationTimeService.cs          |  67 ++++-----
 .../SubsystemOperationTimeController.cs       |   8 +-
 9 files changed, 175 insertions(+), 123 deletions(-)
 create mode 100644 AsbCloudApp/Data/Subsystems/SubsystemsSpinWithDepthDto.cs
 create mode 100644 AsbCloudDb/Model/DefaultData/EntityFillerSubsystem.cs

diff --git a/AsbCloudApp/Data/Subsystems/SubsystemDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemDto.cs
index 7bf2c0b6..515c69a7 100644
--- a/AsbCloudApp/Data/Subsystems/SubsystemDto.cs
+++ b/AsbCloudApp/Data/Subsystems/SubsystemDto.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace AsbCloudApp.Data.Subsystems
+namespace AsbCloudApp.Data.Subsystems
 {
     /// <summary>
     /// Описание параметров подсистемы
diff --git a/AsbCloudApp/Data/Subsystems/SubsystemOperationTimeDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemOperationTimeDto.cs
index ccb923d7..98047c84 100644
--- a/AsbCloudApp/Data/Subsystems/SubsystemOperationTimeDto.cs
+++ b/AsbCloudApp/Data/Subsystems/SubsystemOperationTimeDto.cs
@@ -1,9 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
 namespace AsbCloudApp.Data.Subsystems
 {
     /// <summary>
@@ -15,17 +10,14 @@ namespace AsbCloudApp.Data.Subsystems
         /// Идентификатор 
         /// </summary>
         public int Id { get; set; }
-        /// <summary>
-        /// ИД телеметрии по которой выдается информация
-        /// </summary>
-        public int IdTelemetry { get; set; }
-        public TelemetryBaseDto Telemetry { get; set; }
-        
         /// <summary>
         /// идентификатор подсистемы
         /// </summary>
         public int IdSubsystem { get; set; }
-        public SubsystemDto Subsystem { get; set; }
+        /// <summary>
+        /// Название подсистемы
+        /// </summary>
+        public string SubsystemName { get; set; }
         /// <summary>
         /// дата/время включения подсистемы
         /// </summary>
@@ -42,7 +34,5 @@ namespace AsbCloudApp.Data.Subsystems
         /// глубина забоя на момент выключения подсистемы
         /// </summary>
         public double DepthEnd { get; set; }
-       
-
     }
 }
diff --git a/AsbCloudApp/Data/Subsystems/SubsystemStatDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemStatDto.cs
index 4ef6d98d..8e6f8bf4 100644
--- a/AsbCloudApp/Data/Subsystems/SubsystemStatDto.cs
+++ b/AsbCloudApp/Data/Subsystems/SubsystemStatDto.cs
@@ -1,17 +1,11 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
 namespace AsbCloudApp.Data.Subsystems
 {
     /// <summary>
     /// Статистика подсистемы
     /// </summary>
     public class SubsystemStatDto
-    {        
-       
+    {  
         /// <summary>
         /// Идентификатор подсистемы
         /// </summary>
diff --git a/AsbCloudApp/Data/Subsystems/SubsystemsSpinWithDepthDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemsSpinWithDepthDto.cs
new file mode 100644
index 00000000..196d3ac9
--- /dev/null
+++ b/AsbCloudApp/Data/Subsystems/SubsystemsSpinWithDepthDto.cs
@@ -0,0 +1,30 @@
+using System;
+namespace AsbCloudDb.Model.Subsystems
+{
+    /// <summary>
+    /// Результат запроса в t_telemetry_data_spin, используется фоновым сервисом анализирующим наработки подсистем
+    /// </summary>
+    public class SubsystemsSpinWithDepthDto
+    {
+        /// <summary>
+        /// Режим работы
+        /// </summary>
+        public short Mode { get; set; }
+        /// <summary>
+        /// Состояние
+        /// </summary>
+        public int State { get; set; }
+        /// <summary>
+        /// Дата
+        /// </summary>
+        public DateTimeOffset Date { get; set; }
+        /// <summary>
+        /// Глубина забоя
+        /// </summary>
+        public float Depth { get; set; }
+        /// <summary>
+        /// ИД 
+        /// </summary>
+        public int IdSubsystem { get; set; }
+    }
+}
diff --git a/AsbCloudDb/Model/DefaultData/DefaultData.cs b/AsbCloudDb/Model/DefaultData/DefaultData.cs
index bc405ecb..0bfe29a7 100644
--- a/AsbCloudDb/Model/DefaultData/DefaultData.cs
+++ b/AsbCloudDb/Model/DefaultData/DefaultData.cs
@@ -22,6 +22,7 @@ namespace AsbCloudDb.Model.DefaultData
                 new EntityFillerWellType(),
                 new EntityFillerMeasureCategory(),
                 new EntityFillerCompanyType(),
+                new EntityFillerSubsystem(),
             };
 
             foreach (var filler in fillers)
diff --git a/AsbCloudDb/Model/DefaultData/EntityFillerSubsystem.cs b/AsbCloudDb/Model/DefaultData/EntityFillerSubsystem.cs
new file mode 100644
index 00000000..9e32c4ed
--- /dev/null
+++ b/AsbCloudDb/Model/DefaultData/EntityFillerSubsystem.cs
@@ -0,0 +1,24 @@
+using AsbCloudDb.Model.Subsystems;
+namespace AsbCloudDb.Model.DefaultData
+{  
+    internal class EntityFillerSubsystem : EntityFiller<Subsystem>
+    {
+        protected override Subsystem[] GetData() => new Subsystem[]{
+            // САУБ - ид подсистем с 1 до 65_535
+            new () {Id = 1, Name = "Ручной", Description = "Ручной"},
+            new () {Id = 2, Name = "Бурение в роторе", Description = "Бурение в роторе"},
+            new () {Id = 3, Name = "Проработка", Description = "Проработка"},
+            new () {Id = 4, Name = "Бурение в слайде", Description = "Бурение в слайде"},
+            new () {Id = 5, Name = "Спуск СПО", Description = "Спуск СПО"},
+            new () {Id = 6, Name = "Подъем СПО", Description = "Подъем СПО"},
+            new () {Id = 7, Name = "Подъем с проработкой", Description = "Подъем с проработкой"},
+            new () {Id = 11, Name = "Блокировка", Description = "Блокировка"},
+
+            //Spin master - id подсистем с 65_536 до 131_071 
+            new () {Id = 65536, Name = "Spin master", Description = "Spin master"},
+            new () {Id = 65537, Name = "Torque master", Description = "Torque master"}
+
+
+        };        
+    }
+}
diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs
index ca25f361..f70e181d 100644
--- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs
@@ -6,6 +6,8 @@ using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Hosting;
 using System;
 using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
 using System.Diagnostics;
 using System.Linq;
 using System.Text;
@@ -18,10 +20,12 @@ namespace AsbCloudInfrastructure.Services.Subsystems
     {
         private readonly string connectionString;
         private readonly TimeSpan period = TimeSpan.FromHours(1);
+        private const int idSubsytemTorqueMaster = 65537;
+        private const int idSubsytemSpinMaster = 65536;       
+
         public SubsystemOperationTimeBackgroundService(IConfiguration configuration)
         {
             connectionString = configuration.GetConnectionString("DefaultConnection");
-
         }
         protected override async Task ExecuteAsync(CancellationToken token)
         {
@@ -39,7 +43,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                     {
                         using var context = new AsbCloudDbContext(options);
                         var added = await OperationTimeAllTelemetriesAsync(context, token);
-                        Trace.TraceInformation($"Total operation time subsystem complete. Added {added} operations time.");
+                        Trace.TraceInformation($"Total subsystem operation time complete. Added {added} operations time.");
                     }
                     catch (Exception ex)
                     {
@@ -60,7 +64,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
 
         private static async Task<int> OperationTimeAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token)
         {
-            var lastDetectedDates = await db.DetectedOperations
+            var lastDetectedDates = await db.SubsystemOperationTimes
                 .GroupBy(o => o.IdTelemetry)
                 .Select(g => new
                 {
@@ -87,19 +91,19 @@ namespace AsbCloudInfrastructure.Services.Subsystems
             foreach (var item in JounedlastDetectedDates)
             {
                 var stopwatch = Stopwatch.StartNew();
-                var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
-                //var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
+                var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);                
                 stopwatch.Stop();
-                if (newOperationsSaub.Any())
+                if (newOperationsSaub is not null && newOperationsSaub.Any())
                 {
                     db.SubsystemOperationTimes.AddRange(newOperationsSaub);
                     affected += await db.SaveChangesAsync(token);
                 }
-                //if (newOperationsSpin.Any())
-                //{
-                //    db.SubsystemOperationTimes.AddRange(newOperationsSpin);
-                //    affected += await db.SaveChangesAsync(token);
-                //}
+                var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
+                if (newOperationsSpin is not null && newOperationsSpin.Any())
+                {
+                    db.SubsystemOperationTimes.AddRange(newOperationsSpin);
+                    affected += await db.SaveChangesAsync(token);
+                }
             }
             return affected;
         }
@@ -115,8 +119,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                     Mode = d.Mode,
                     Depth = d.WellDepth
                 })
-                .OrderBy(d => d.DateTime);            
-
+                .OrderBy(d => d.DateTime);
             var take = 4 * 86_400; // 4 дня
             var startDate = begin;            
             var firstItem = query.FirstOrDefault();
@@ -125,8 +128,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
             short? mode = firstItem.Mode;
             DateTimeOffset dateBegin = firstItem.DateTime;
             float? depthStart = firstItem.Depth;
-            var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
-            
+            var resultSubsystemOperationTime = new List<SubsystemOperationTime>();            
             var data = await query
                 .Where(d => d.DateTime > startDate)
                 .Take(take)
@@ -139,11 +141,10 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                         {
                             IdTelemetry = idTelemetry,
                             DateStart = dateBegin,
-                            IdSubsystem = (int)data[i - 1].Mode,
+                            IdSubsystem = (int)data[i - 1].Mode + 1,
                             DateEnd = data[i - 1].DateTime,
                             DepthStart = depthStart,
                             DepthEnd = data[i - 1].Depth
-
                         };
                         resultSubsystemOperationTime.Add(operationTimeItem);
                         mode = data[i].Mode;
@@ -151,64 +152,97 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                         depthStart = data[i].Depth;
                     }
                 }
-                startDate = data.Last().DateTime;            
-            
+                startDate = data.Last().DateTime; 
             return resultSubsystemOperationTime;
         }
-
-
         private static async Task<IEnumerable<SubsystemOperationTime>> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
         {
-            var query = db.TelemetryDataSpin
-                .AsNoTracking()
-                .Where(d => d.IdTelemetry == idTelemetry)
-                .Select(d => new 
+            Predicate<int> isSubsystemTorqueState = (int state) => state == 7;
+            Predicate<short> isSubsystemTorqueMode = (short mode) => (mode & 2) > 0;
+            Predicate<int> isSubsystemSpin = (int state) => state != 0 & state != 6 & state != 7;
+            var operationTimeSpinWithDepth =
+                $"select tspin.\"date\", tspin.\"mode\", tspin.\"state\", tsaub.\"well_depth\"" +
+                $" from (select \"date\" ,\"mode\" ,lag(mode, 1) over (order by \"date\") as mode_pre, state , " +
+                $"lag(state, 1) over (order by \"date\") as state_pre from t_telemetry_data_spin where id_telemetry = {idTelemetry}) as tspin " +
+                $"join (select \"date\", well_depth from t_telemetry_data_saub where id_telemetry = {idTelemetry}) as tsaub " +
+                $"on EXTRACT(EPOCH from tspin.date) = EXTRACT(EPOCH from tsaub.date) " +
+                $"where mode!=mode_pre or state != state_pre order by \"date\";";            
+            using var command = db.Database.GetDbConnection().CreateCommand();
+            command.CommandText = operationTimeSpinWithDepth;
+            db.Database.OpenConnection();
+            using var result = command.ExecuteReader();
+            var query = new List<SubsystemsSpinWithDepthDto>();
+            //DataTable dt = new DataTable();
+            //dt.Load(result);
+            //var query = from c in dt.AsEnumerable()                             
+            //                select new
+            //                {
+            //                    Date = (DateTimeOffset)c["date"],
+            //                    Mode = (short)c["mode"],
+            //                    State = (int)c["state"],
+            //                    Depth = (float)c["float"]
+            //                };
+            if (result.HasRows)
+                while (result.Read())
                 {
-                    DateTime = d.DateTime,
-                    Mode = d.Mode,
-                    Depth = db.TelemetryDataSaub.Where(t => t.DateTime == d.DateTime & t.IdTelemetry ==idTelemetry)
-                            .GroupBy(t => t.IdTelemetry)
-                            .Select(group => group.Min(t => t.WellDepth))
-                            .FirstOrDefault()
-                })
-                .OrderBy(d => d.DateTime);            
-
+                    var itemEntity = new SubsystemsSpinWithDepthDto()
+                    {
+                        Date = result.GetFieldValue<DateTimeOffset>(0),
+                        Mode = result.GetFieldValue<short>(1),
+                        State = result.GetFieldValue<int>(2),
+                        Depth = result.GetFieldValue<float>(3)
+                    };
+                    int? subsystemId = isSubsystemTorqueState(itemEntity.State) && isSubsystemTorqueMode(itemEntity.Mode)
+                        ? idSubsytemTorqueMaster
+                        : isSubsystemSpin(itemEntity.State)
+                            ? idSubsytemSpinMaster
+                            : 0;
+                    if (subsystemId.HasValue)
+                    {
+                        itemEntity.IdSubsystem = subsystemId.Value;
+                        query.Add(itemEntity);
+                    }
+                }
             var take = 4 * 86_400; // 4 дня
             var startDate = begin;
             var firstItem = query.FirstOrDefault();
             if (firstItem is null)
-                return null;
-            short? mode = firstItem.Mode;
-            DateTimeOffset dateBegin = firstItem.DateTime;
+                return null;            
+            int idSubsystem = firstItem.IdSubsystem;
+            DateTimeOffset dateBegin = firstItem.Date;
             float? depthStart = firstItem.Depth;
             var resultSubsystemOperationTime = new List<SubsystemOperationTime>();            
-            var data = await query
-                .Where(d => d.DateTime > startDate)
+            var data = query
+                .Where(d => d.Date > startDate)
                 .Take(take)
-                .ToArrayAsync(token);
+                .ToArray();
+            if (data.Length==0)
+                return null;
            
             for (int i = 1; i < data.Length; i++)
             {
-                if (data[i].Mode != mode)
+                if (data[i].IdSubsystem != idSubsystem)
                 {
                     var operationTimeItem = new SubsystemOperationTime()
                     {
                         IdTelemetry = idTelemetry,
                         DateStart = dateBegin,
-                        IdSubsystem = (int)data[i - 1].Mode,
-                        DateEnd = data[i - 1].DateTime,
+                        IdSubsystem = data[i - 1].IdSubsystem,
+                        DateEnd = data[i - 1].Date,
                         DepthStart = depthStart,
                         DepthEnd = data[i - 1].Depth
 
-                    };
-                    resultSubsystemOperationTime.Add(operationTimeItem);
-                    mode = data[i].Mode;
-                    dateBegin = data[i].DateTime;
+                    };                                        
+                    dateBegin = data[i].Date;
                     depthStart = data[i].Depth;
+                    idSubsystem = data[i].IdSubsystem;
+                    if (data[i-1].IdSubsystem != 0)
+                    {
+                        resultSubsystemOperationTime.Add(operationTimeItem);
+                    }                    
                 }
-            }
-            startDate = data.Last().DateTime;
-
+            }            
+            startDate = data.LastOrDefault().Date;
             return resultSubsystemOperationTime;
         }        
     }
diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs
index 2a793d1a..ff379581 100644
--- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs
+++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs
@@ -1,11 +1,11 @@
-using AsbCloudApp.Data.Subsystems;
+using AsbCloudApp.Data;
+using AsbCloudApp.Data.Subsystems;
 using AsbCloudApp.Requests;
 using AsbCloudApp.Services;
 using AsbCloudApp.Services.Subsystems;
 using AsbCloudDb;
 using AsbCloudDb.Model;
 using AsbCloudDb.Model.Subsystems;
-using AsbCloudInfrastructure.Repository;
 using Mapster;
 using Microsoft.EntityFrameworkCore;
 using System;
@@ -23,9 +23,6 @@ namespace AsbCloudInfrastructure.Services.Subsystems
         private readonly IAsbCloudDbContext db;
         private readonly IWellService wellService;
         private readonly ICrudService<SubsystemDto> subsystemService;
-        
-
-
         public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, ICrudService<SubsystemDto> subsystemService)
         {
             this.db = db;
@@ -33,7 +30,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
             this.subsystemService = subsystemService;
         }
 
-        private async Task<IEnumerable<SubsystemDto>> GetSubsystemByIdWellAsync(int idWell, CancellationToken token)
+        private async Task<IEnumerable<SubsystemDto>?> GetSubsystemByIdWellAsync(int idWell, CancellationToken token)
         {
             var well = await wellService.GetOrDefaultAsync(idWell, token);
             if (well?.IdTelemetry is null || well.Timezone is null)
@@ -53,39 +50,37 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                 .ToListAsync(token);
             return wellSubsystem;
         }
-
-        public async Task<IEnumerable<SubsystemDto>> GetSubsystemAsync(int? idWell, CancellationToken token)
+        public async Task<IEnumerable<SubsystemDto>?> GetSubsystemAsync(int? idWell, CancellationToken token)
         {
-            if (idWell is null)
+            if (idWell.HasValue)
             {
-                var subsystem = await subsystemService.GetAllAsync(token);
-                return subsystem;
-            }
-            var subsystemWell = await GetSubsystemAsync(idWell, token);
-            return subsystemWell;
-
+                var subsystemWell = await GetSubsystemByIdWellAsync(idWell.Value, token);
+                return subsystemWell;
+            }            
+            var subsystem = await subsystemService.GetAllAsync(token);
+            return subsystem;
         }
-
-
         public async Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token)
         {
             var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
             if (well?.IdTelemetry is null || well.Timezone is null)
                 return 0;
             var query = BuildQuery(request);
+            if (query is null)
+                return 0;
             db.SubsystemOperationTimes.RemoveRange(query);
             return await db.SaveChangesAsync(token);
         }
 
-        public async Task<IEnumerable<SubsystemOperationTimeDto>> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
-        {  
-            var query = BuildQuery(request)
-                .AsNoTracking();
+        public async Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
+        {
+            var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
+            if (well?.IdTelemetry is null || well.Timezone is null)
+                return null;
+            var query = BuildQuery(request);
             if (query is null)
                 return null;
-
             var data = await query.ToListAsync(token);
-
             if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeInner) 
             {
                 if (request.GtDate is not null)
@@ -100,22 +95,20 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                 var end = request.GtDate ?? throw new ArgumentNullException(nameof(request.LtDate));
                 data = Trim(data, begin,end );
             }
-            var dtos = data.Select(o => Convert(o));
+            var dtos = data.Select(o => Convert(o,well));
             return dtos;
         }
-
-       
-
         public async Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token)
         {
             var data = await GetOperationTimeAsync(request, token);
+            if (data is null)
+                return null;
             var statList = CalcStat(data, request);
             return statList;
         }
-
         private List<SubsystemOperationTime> Trim(List<SubsystemOperationTime> data, DateTime gtDate, DateTime ltDate)
         {           
-            var itemsToTrim = data.Where(q => true)
+            var itemsToTrim = data.Where(q => q.DateStart == gtDate & q.DateEnd == ltDate)
                 .Select(o => new SubsystemOperationTime
                 {
                     Id = o.Id,
@@ -131,7 +124,6 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                 .ToList();
             return itemsToTrim;
         }
-
         private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> groupedData, SubsystemOperationTimeRequest request)
         {
             var result = new List<SubsystemStatDto>();
@@ -151,8 +143,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
                 var subsystemStat = new SubsystemStatDto()
                 {
                     IdSubsystem = idSubsystem,
-                    Subsystem = subsystemService.GetOrDefault(idSubsystem)?.Name ?? "unknown",
-                    //Subsystem = db.Subsystems.Where(n => n.Id == idSubsystem).FirstOrDefault()?.Name ?? "unknown",
+                    Subsystem = subsystemService.GetOrDefault(idSubsystem)?.Name ?? "unknown",                    
                     UsedTimeHours = TimeSpan.FromHours(periodGroup),
                     KUsage = 1d*periodGroup / periodRequest,
                     K2 = 1d*periodGroup / periodGroupTotal,
@@ -161,8 +152,6 @@ namespace AsbCloudInfrastructure.Services.Subsystems
             }
             return result;
         }
-        
-
         private IQueryable<SubsystemOperationTime>? BuildQuery(SubsystemOperationTimeRequest request)
         {
             var idTelemetry = wellService.GetOrDefault(request.IdWell)?.IdTelemetry;
@@ -210,15 +199,13 @@ namespace AsbCloudInfrastructure.Services.Subsystems
 
             return query;
         }
-
-        private SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime)
+        private SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well)
         {
-            var dto = operationTime.Adapt<SubsystemOperationTimeDto>();           
+            var dto = operationTime.Adapt<SubsystemOperationTimeDto>();
+            dto.DateStart = operationTime.DateStart.ToRemoteDateTime(well.Timezone.Hours);
+            dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(well.Timezone.Hours);
             return dto;
         }
-
-
-
     }
 #nullable disable
 }
diff --git a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs
index ba75773a..e4d15ebc 100644
--- a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs
+++ b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs
@@ -19,13 +19,11 @@ namespace AsbCloudWebApi.Controllers.Subsystems
     [Authorize]
     public class SubsystemOperationTimeController : ControllerBase
     {
-        private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
-        private readonly ICrudService<SubsystemDto> subsystemService;
+        private readonly ISubsystemOperationTimeService subsystemOperationTimeService;        
         private readonly IWellService wellService;
-        public SubsystemOperationTimeController(ISubsystemOperationTimeService subsystemOperationTimeService, ICrudService<SubsystemDto> subsystemService, IWellService wellService)
+        public SubsystemOperationTimeController(ISubsystemOperationTimeService subsystemOperationTimeService, IWellService wellService)
         {
-            this.subsystemOperationTimeService = subsystemOperationTimeService;
-            this.subsystemService = subsystemService;
+            this.subsystemOperationTimeService = subsystemOperationTimeService;          
             this.wellService = wellService;
         }
         /// <summary>