From fce20a2a1000041de6d994f2e5acc66fd20e3348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Fri, 23 Apr 2021 10:21:25 +0500 Subject: [PATCH] autocleanup --- AsbCloud.sln | 8 +- AsbCloudApp/AsbCloudApp.csproj | 4 - AsbCloudApp/Data/DataSaubBaseDto.cs | 44 +- AsbCloudApp/Data/EventDto.cs | 12 + AsbCloudApp/Data/MessageDto.cs | 20 + AsbCloudApp/Data/PaginationContainer.cs | 43 + AsbCloudApp/Data/TelemetryDataDto.cs | 28 - AsbCloudApp/Data/TelemetryDto.cs | 9 + AsbCloudApp/Data/TelemetryInfoDto.cs | 7 +- AsbCloudApp/Data/TelemetryMessageDto.cs | 25 + AsbCloudApp/Data/TelemetryUserDto.cs | 15 + AsbCloudApp/Data/UserBaseDto.cs | 6 +- AsbCloudApp/Data/UserDto.cs | 2 +- AsbCloudApp/Data/UserTokenDto.cs | 8 +- ...elemetryDataService.cs => IDataService.cs} | 4 +- AsbCloudApp/Services/IDepositService.cs | 6 - AsbCloudApp/Services/IEventService.cs | 10 + AsbCloudApp/Services/IMessageService.cs | 12 + AsbCloudApp/Services/ITelemetryService.cs | 9 +- AsbCloudApp/Services/ITelemetryUserService.cs | 10 + AsbCloudDb/Model/AsbCloudDbContext.cs | 42 +- AsbCloudDb/Model/Cluster.cs | 2 +- AsbCloudDb/Model/Customer.cs | 3 +- AsbCloudDb/Model/DataSaubBase.cs | 42 +- AsbCloudDb/Model/Deposit.cs | 2 +- AsbCloudDb/Model/Event.cs | 28 +- AsbCloudDb/Model/IId.cs | 6 +- AsbCloudDb/Model/Message.cs | 17 +- AsbCloudDb/Model/Telemetry.cs | 24 +- AsbCloudDb/Model/TelemetryInfo.cs | 19 + AsbCloudDb/Model/TelemetryUser.cs | 34 +- AsbCloudDb/Model/User.cs | 24 +- AsbCloudDb/Model/Well.cs | 2 +- AsbCloudInfrastructure/DependencyInjection.cs | 11 +- .../Services/AuthService.cs | 2 +- .../Services/Cache/CacheDb.cs | 11 +- .../Services/Cache/CacheTable.cs | 170 ++- .../Services/Cache/ICacheTable.cs | 4 + ...TelemetryDataService.cs => DataService.cs} | 39 +- .../Services/DepositService.cs | 19 - .../Services/EventService.cs | 56 + .../Services/MessageService.cs | 127 ++ .../Services/TelemetryService.cs | 73 +- .../Services/TelemetryUserService.cs | 58 + .../Services/WellService.cs | 7 +- AsbCloudWebApi/Controllers/AuthController.cs | 2 +- AsbCloudWebApi/Controllers/DataController.cs | 8 +- .../Controllers/MessageController.cs | 45 + .../Controllers/TelemetryController.cs | 77 +- AsbCloudWebApi/DependencyInjection.cs | 6 +- AsbCloudWebApi/SignalR/ITelemetryHubClient.cs | 6 +- AsbCloudWebApi/TODO.md | 2 +- AsbCloudWebApi/wwwroot/index.html | 2 +- AsbCloudWebApi/кейсы для админки.txt | 6 + ConsoleApp1/Program.cs | 34 +- ConsoleApp1/Table.cs | 8 +- ConsoleApp1/TableMapper.cs | 8 +- SaubPanelOnlineSender/DbPlayerService.cs | 54 +- SyncDicts/Program.cs | 112 ++ SyncDicts/SyncDicts.csproj | 23 + swagger.json | 1022 +++++++++++++++++ 61 files changed, 2182 insertions(+), 337 deletions(-) create mode 100644 AsbCloudApp/Data/EventDto.cs create mode 100644 AsbCloudApp/Data/MessageDto.cs create mode 100644 AsbCloudApp/Data/PaginationContainer.cs delete mode 100644 AsbCloudApp/Data/TelemetryDataDto.cs create mode 100644 AsbCloudApp/Data/TelemetryDto.cs create mode 100644 AsbCloudApp/Data/TelemetryMessageDto.cs create mode 100644 AsbCloudApp/Data/TelemetryUserDto.cs rename AsbCloudApp/Services/{ITelemetryDataService.cs => IDataService.cs} (71%) delete mode 100644 AsbCloudApp/Services/IDepositService.cs create mode 100644 AsbCloudApp/Services/IEventService.cs create mode 100644 AsbCloudApp/Services/IMessageService.cs create mode 100644 AsbCloudApp/Services/ITelemetryUserService.cs create mode 100644 AsbCloudDb/Model/TelemetryInfo.cs rename AsbCloudInfrastructure/Services/{TelemetryDataService.cs => DataService.cs} (63%) delete mode 100644 AsbCloudInfrastructure/Services/DepositService.cs create mode 100644 AsbCloudInfrastructure/Services/EventService.cs create mode 100644 AsbCloudInfrastructure/Services/MessageService.cs create mode 100644 AsbCloudInfrastructure/Services/TelemetryUserService.cs create mode 100644 AsbCloudWebApi/Controllers/MessageController.cs create mode 100644 AsbCloudWebApi/кейсы для админки.txt create mode 100644 SyncDicts/Program.cs create mode 100644 SyncDicts/SyncDicts.csproj create mode 100644 swagger.json diff --git a/AsbCloud.sln b/AsbCloud.sln index b586b80d..1266d4fb 100644 --- a/AsbCloud.sln +++ b/AsbCloud.sln @@ -13,7 +13,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp1", "ConsoleApp1\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsbCloudDb", "AsbCloudDb\AsbCloudDb.csproj", "{40FBD29B-724B-4496-B5D9-1A5D14102456}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaubPanelOnlineSender", "SaubPanelOnlineSender\SaubPanelOnlineSender.csproj", "{B156D582-4D32-4368-A103-687D15B9846C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaubPanelOnlineSender", "SaubPanelOnlineSender\SaubPanelOnlineSender.csproj", "{B156D582-4D32-4368-A103-687D15B9846C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyncDicts", "SyncDicts\SyncDicts.csproj", "{39DA5EFF-D018-45AE-B0A0-A241B488660F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -45,6 +47,10 @@ Global {B156D582-4D32-4368-A103-687D15B9846C}.Debug|Any CPU.Build.0 = Debug|Any CPU {B156D582-4D32-4368-A103-687D15B9846C}.Release|Any CPU.ActiveCfg = Release|Any CPU {B156D582-4D32-4368-A103-687D15B9846C}.Release|Any CPU.Build.0 = Release|Any CPU + {39DA5EFF-D018-45AE-B0A0-A241B488660F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39DA5EFF-D018-45AE-B0A0-A241B488660F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39DA5EFF-D018-45AE-B0A0-A241B488660F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39DA5EFF-D018-45AE-B0A0-A241B488660F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AsbCloudApp/AsbCloudApp.csproj b/AsbCloudApp/AsbCloudApp.csproj index 8e347065..a20524d3 100644 --- a/AsbCloudApp/AsbCloudApp.csproj +++ b/AsbCloudApp/AsbCloudApp.csproj @@ -8,8 +8,4 @@ - - - - diff --git a/AsbCloudApp/Data/DataSaubBaseDto.cs b/AsbCloudApp/Data/DataSaubBaseDto.cs index 997636fe..b4e86b22 100644 --- a/AsbCloudApp/Data/DataSaubBaseDto.cs +++ b/AsbCloudApp/Data/DataSaubBaseDto.cs @@ -1,8 +1,10 @@ using System; -using System.Text.Json.Serialization; namespace AsbCloudApp.Data { + /// + /// Сообщение получаемое по телеметрии и отправляемое в frontend + /// public class DataSaubBaseDto { //[JsonPropertyName("date")] @@ -20,6 +22,11 @@ namespace AsbCloudApp.Data /// public int? Mode { get; set; } + /// + /// telemetry user + /// + public string User { get; set; } + /// /// Глубина забоя /// @@ -31,9 +38,19 @@ namespace AsbCloudApp.Data public double? BitDepth { get; set; } /// - /// Талевый блок. Высота + /// Талевый блок. Положение /// - public double? BlockHeight { get; set; } + public double? BlockPosition { get; set; } + + /// + /// Талевый блок. Мин положение + /// + public double? BlockPositionMin { get; set; } + + /// + /// Талевый блок. Макс положение + /// + public double? BlockPositionMax { get; set; } /// /// Талевый блок. Скорость @@ -45,6 +62,21 @@ namespace AsbCloudApp.Data /// public double? BlockSpeedSp { get; set; } + /// + /// Талевый блок. Задание скорости для роторного бурения + /// + public double? BlockSpeedSpRotor { get; set; } + + /// + /// Талевый блок. Задание скорости для режима слайда + /// + public double? BlockSpeedSpSlide { get; set; } + + /// + /// Талевый блок. Задание скорости для проработки + /// + public double? BlockSpeedSpDevelop { get; set; } + /// /// Давтение /// @@ -57,6 +89,12 @@ namespace AsbCloudApp.Data public double? PressureSp { get; set; } + public double? PressureSpRotor { get; set; } + + public double? PressureSpSlide { get; set; } + + public double? PressureSpDevelop { get; set; } + public double? PressureDeltaLimitMax { get; set; } public double? AxialLoad { get; set; } diff --git a/AsbCloudApp/Data/EventDto.cs b/AsbCloudApp/Data/EventDto.cs new file mode 100644 index 00000000..db912ebb --- /dev/null +++ b/AsbCloudApp/Data/EventDto.cs @@ -0,0 +1,12 @@ +namespace AsbCloudApp.Data +{ + public class EventDto + { + public int Id { get; set; } + public string Message { get; set; } + public int IdCategory { get; set; } + public string Tag { get; set; } + public int EventType { get; set; } + public int IdSound { get; set; } + } +} diff --git a/AsbCloudApp/Data/MessageDto.cs b/AsbCloudApp/Data/MessageDto.cs new file mode 100644 index 00000000..bbb4256d --- /dev/null +++ b/AsbCloudApp/Data/MessageDto.cs @@ -0,0 +1,20 @@ +using System; + +namespace AsbCloudApp.Data +{ + /// + /// Сообщение для frontend + /// + public class MessageDto + { + public int Id { get; set; } + + public DateTime Date { get; set; } + + public int CategoryId { get; set; } + + public string User { get; set; } + + public string Message { get; set; } + } +} diff --git a/AsbCloudApp/Data/PaginationContainer.cs b/AsbCloudApp/Data/PaginationContainer.cs new file mode 100644 index 00000000..7ddb3921 --- /dev/null +++ b/AsbCloudApp/Data/PaginationContainer.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AsbCloudApp.Data +{ + /// + /// Контейнер для поддержки постраничного просмотра таблиц + /// + /// + public class PaginationContainer + { + public PaginationContainer() + { + Items = new List(4); + } + + public PaginationContainer(int capacity) + { + Items = new List(capacity); + } + + /// + /// Кол-во записей пропущеных с начала таблицы в запросе от api + /// + public int Skip { get; set; } + + /// + /// Кол-во записей в запросе от api + /// + public int Take { get; set; } + + /// + /// Кол-во записей всего в таблице + /// + public int Count { get; set; } + + /// + /// Данные + /// + public List Items { get; set; } + } +} diff --git a/AsbCloudApp/Data/TelemetryDataDto.cs b/AsbCloudApp/Data/TelemetryDataDto.cs deleted file mode 100644 index 7784c0b9..00000000 --- a/AsbCloudApp/Data/TelemetryDataDto.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace AsbCloudApp.Data -{ - /// - /// Формат посылки от панели к облаку. - /// Панель копит у себя данные и при удачной отправке помечает как отправленные. - /// - public class TelemetryDataDto - { - public DateTime Date { get; set; } - - /// - /// Версия ПО панели. - /// Нужна будет для разбора информации - /// - public string HmiVersion { get; set; } - public string UserName { get; set; } - public List DataSaub { get; set; } - - /// TODO: - //public List EventsDictiotary { get; set; } - - //public List Messages { get; set; } - } -} diff --git a/AsbCloudApp/Data/TelemetryDto.cs b/AsbCloudApp/Data/TelemetryDto.cs new file mode 100644 index 00000000..ab19052b --- /dev/null +++ b/AsbCloudApp/Data/TelemetryDto.cs @@ -0,0 +1,9 @@ +namespace AsbCloudApp.Data +{ + public class TelemetryDto + { + public string HmiVersion { get; set; } + + public T Payload { get; set; } + } +} diff --git a/AsbCloudApp/Data/TelemetryInfoDto.cs b/AsbCloudApp/Data/TelemetryInfoDto.cs index c0dec52f..7d6a964b 100644 --- a/AsbCloudApp/Data/TelemetryInfoDto.cs +++ b/AsbCloudApp/Data/TelemetryInfoDto.cs @@ -1,14 +1,17 @@ using System; -using System.Collections.Generic; -using System.Text; namespace AsbCloudApp.Data { public class TelemetryInfoDto { public DateTime Date { get; set; } + public string TimeZoneId { get; set; } + public double TimeZoneOffsetTotalHours { get; set; } public string Caption { get; set; } public string Cluster { get; set; } public string Deposit { get; set; } + public string HmiVersion { get; set; } + public string PlcVersion { get; set; } + public string Comment { get; set; } } } diff --git a/AsbCloudApp/Data/TelemetryMessageDto.cs b/AsbCloudApp/Data/TelemetryMessageDto.cs new file mode 100644 index 00000000..34f452cd --- /dev/null +++ b/AsbCloudApp/Data/TelemetryMessageDto.cs @@ -0,0 +1,25 @@ +using System; + +namespace AsbCloudApp.Data +{ + /// + /// Сообщение получаемое от телеметрии + /// + public class TelemetryMessageDto + { + public int Id { get; set; } + + public DateTime Date { get; set; } + + public int IdEvent { get; set; } + + public int? State { get; set; } + + public int? IdTelemetryUser { get; set; } + + public string Arg0 { get; set; } + public string Arg1 { get; set; } + public string Arg2 { get; set; } + public string Arg3 { get; set; } + } +} diff --git a/AsbCloudApp/Data/TelemetryUserDto.cs b/AsbCloudApp/Data/TelemetryUserDto.cs new file mode 100644 index 00000000..e4d47444 --- /dev/null +++ b/AsbCloudApp/Data/TelemetryUserDto.cs @@ -0,0 +1,15 @@ +namespace AsbCloudApp.Data +{ + public class TelemetryUserDto + { + public int Id { get; set; } + + public string Name { get; set; } + + public string Surname { get; set; } + + public string Patronymic { get; set; } + + public int Level { get; set; } + } +} diff --git a/AsbCloudApp/Data/UserBaseDto.cs b/AsbCloudApp/Data/UserBaseDto.cs index 15f28ef7..1c4c8d00 100644 --- a/AsbCloudApp/Data/UserBaseDto.cs +++ b/AsbCloudApp/Data/UserBaseDto.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace AsbCloudApp.Data +namespace AsbCloudApp.Data { public class UserBaseDto { diff --git a/AsbCloudApp/Data/UserDto.cs b/AsbCloudApp/Data/UserDto.cs index 3a439090..a2603315 100644 --- a/AsbCloudApp/Data/UserDto.cs +++ b/AsbCloudApp/Data/UserDto.cs @@ -1,6 +1,6 @@ namespace AsbCloudApp.Data { - public class UserDto: UserBaseDto + public class UserDto : UserBaseDto { public int Id { get; set; } diff --git a/AsbCloudApp/Data/UserTokenDto.cs b/AsbCloudApp/Data/UserTokenDto.cs index 167923ec..4fb4cf04 100644 --- a/AsbCloudApp/Data/UserTokenDto.cs +++ b/AsbCloudApp/Data/UserTokenDto.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace AsbCloudApp.Data +namespace AsbCloudApp.Data { - public class UserTokenDto: UserBaseDto + public class UserTokenDto : UserBaseDto { public int Id { get; set; } public string CustomerName { get; set; } diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/IDataService.cs similarity index 71% rename from AsbCloudApp/Services/ITelemetryDataService.cs rename to AsbCloudApp/Services/IDataService.cs index c579b932..168b1d6b 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/IDataService.cs @@ -4,8 +4,10 @@ using System.Collections.Generic; namespace AsbCloudApp.Services { - public interface ITelemetryDataService + public interface IDataService { IEnumerable Get(int wellId, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024); + + void UpdateData(string uid, IEnumerable dtos); } } \ No newline at end of file diff --git a/AsbCloudApp/Services/IDepositService.cs b/AsbCloudApp/Services/IDepositService.cs deleted file mode 100644 index d3050d7d..00000000 --- a/AsbCloudApp/Services/IDepositService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AsbCloudApp.Services -{ - public interface IDepositService - { - } -} diff --git a/AsbCloudApp/Services/IEventService.cs b/AsbCloudApp/Services/IEventService.cs new file mode 100644 index 00000000..87f55ad7 --- /dev/null +++ b/AsbCloudApp/Services/IEventService.cs @@ -0,0 +1,10 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; + +namespace AsbCloudApp.Services +{ + public interface IEventService + { + void Upsert(string uid, IEnumerable dtos); + } +} diff --git a/AsbCloudApp/Services/IMessageService.cs b/AsbCloudApp/Services/IMessageService.cs new file mode 100644 index 00000000..69450565 --- /dev/null +++ b/AsbCloudApp/Services/IMessageService.cs @@ -0,0 +1,12 @@ +using AsbCloudApp.Data; +using System; +using System.Collections.Generic; + +namespace AsbCloudApp.Services +{ + public interface IMessageService + { + PaginationContainer GetMessages(int wellId, IEnumerable categoryids = null, DateTime begin = default, DateTime end = default, int skip = 0, int take = 32); + void Insert(string uid, IEnumerable dtos); + } +} \ No newline at end of file diff --git a/AsbCloudApp/Services/ITelemetryService.cs b/AsbCloudApp/Services/ITelemetryService.cs index 1b421367..a59a57fa 100644 --- a/AsbCloudApp/Services/ITelemetryService.cs +++ b/AsbCloudApp/Services/ITelemetryService.cs @@ -1,16 +1,11 @@ using AsbCloudApp.Data; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace AsbCloudApp.Services { public interface ITelemetryService { - int? GetWellIdByUid(string uid); - void UpdateData(string uid, TelemetryDataDto data); + int? GetWellIdByTelemetryUid(string uid); + int GetOrCreateTemetryIdByUid(string uid); void UpdateInfo(string uid, TelemetryInfoDto info); } } diff --git a/AsbCloudApp/Services/ITelemetryUserService.cs b/AsbCloudApp/Services/ITelemetryUserService.cs new file mode 100644 index 00000000..80c465a3 --- /dev/null +++ b/AsbCloudApp/Services/ITelemetryUserService.cs @@ -0,0 +1,10 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; + +namespace AsbCloudApp.Services +{ + public interface ITelemetryUserService + { + void Upsert(string uid, IEnumerable dtos); + } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index e91b608d..75527dde 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -11,7 +11,7 @@ namespace AsbCloudDb.Model //Scaffold-DbContext "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Model -DataAnnotations public partial class AsbCloudDbContext : DbContext, IAsbCloudDbContext { - private readonly string connectionString; + //private readonly string connectionString; public virtual DbSet Clusters { get; set; } public virtual DbSet Customers { get; set; } public virtual DbSet DataSaubBases { get; set; } @@ -36,13 +36,13 @@ namespace AsbCloudDb.Model Database.EnsureCreated(); } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - if (!optionsBuilder.IsConfigured) - { - optionsBuilder.UseNpgsql(connectionString); - } - } + //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + //{ + // if (!optionsBuilder.IsConfigured) + // { + // optionsBuilder.UseNpgsql(connectionString); + // } + //} protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -76,25 +76,35 @@ namespace AsbCloudDb.Model modelBuilder.Entity(entity => { + entity.HasKey(nameof(TelemetryUser.IdTelemetry), nameof(TelemetryUser.IdUser)); entity.HasOne(d => d.Telemetry) - .WithMany() + .WithMany(p => p.Users) .HasForeignKey(d => d.IdTelemetry) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("t_telemetry_user_t_telemetry_id_fk"); }); + modelBuilder.Entity(entity => + { + entity.HasKey(nameof(Event.IdTelemetry), nameof(Event.IdEvent)); + entity.HasOne(d => d.Telemetry) + .WithMany(p => p.Events) + .HasForeignKey(d => d.IdTelemetry) + .HasConstraintName("t_event_t_telemetry_id_fk"); + }); + modelBuilder.Entity(entity => { entity.HasData(new List{ new UserRole{ Id = 1, Caption = "Администратор", }, - }); ; + }); }); modelBuilder.Entity(entity => { entity.HasData(new List{ new Customer{ Id = 1, Caption = "\"ООО\" АСБ", }, - }); ; + }); }); modelBuilder.Entity(entity => @@ -148,14 +158,14 @@ namespace AsbCloudDb.Model modelBuilder.Entity(entity => { entity.HasData(new List { - new Deposit{Id = 1, Caption = "месторождение" }, + new Deposit{Id = 1, Caption = "м/р 1" }, }); }); modelBuilder.Entity(entity => { entity.HasData(new List { - new Cluster{Id = 1, Caption = "месторождение", IdDeposit = 1 }, + new Cluster{Id = 1, Caption = "куст 1", IdDeposit = 1 }, }); }); @@ -185,17 +195,17 @@ namespace AsbCloudDb.Model .Where(e => e.Login == login); public async Task CreatePartitionAsync(string propertyName, int id, CancellationToken token = default) - where TEntity: class + where TEntity : class { var dbSet = Set(); var baseTableName = dbSet.EntityType.GetTableName(); var schema = dbSet.EntityType.GetSchema(); var tableObject = Microsoft.EntityFrameworkCore.Metadata.StoreObjectIdentifier.Table(baseTableName, schema); - var tableName = baseTableName.Replace("_base", ""); + var tableName = baseTableName.Replace("_base", ""); var property = dbSet.EntityType.GetProperty(propertyName).GetColumnName(tableObject); var query = $"CREATE TABLE {tableName}_{id} (like {baseTableName} including all, constraint partitioning_check check ({property} = 1)) INHERITS ({baseTableName});"; - + return await Database.ExecuteSqlRawAsync(query, token).ConfigureAwait(false); } } diff --git a/AsbCloudDb/Model/Cluster.cs b/AsbCloudDb/Model/Cluster.cs index 77b06b61..0723dc39 100644 --- a/AsbCloudDb/Model/Cluster.cs +++ b/AsbCloudDb/Model/Cluster.cs @@ -8,7 +8,7 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_cluster"), Comment("Кусты")] - public partial class Cluster: IId + public partial class Cluster : IId { public Cluster() { diff --git a/AsbCloudDb/Model/Customer.cs b/AsbCloudDb/Model/Customer.cs index d598dd76..cb4f2e9e 100644 --- a/AsbCloudDb/Model/Customer.cs +++ b/AsbCloudDb/Model/Customer.cs @@ -7,7 +7,7 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_customer")] - public partial class Customer: IId + public partial class Customer : IId { public Customer() { @@ -24,6 +24,7 @@ namespace AsbCloudDb.Model [InverseProperty(nameof(User.Customer))] public virtual ICollection Users { get; set; } + [InverseProperty(nameof(Well.Customer))] public virtual ICollection Wells { get; set; } } diff --git a/AsbCloudDb/Model/DataSaubBase.cs b/AsbCloudDb/Model/DataSaubBase.cs index a7585815..c051ce22 100644 --- a/AsbCloudDb/Model/DataSaubBase.cs +++ b/AsbCloudDb/Model/DataSaubBase.cs @@ -14,28 +14,66 @@ namespace AsbCloudDb.Model [Key] [Column("id")] public int Id { get; set; } + [Column("id_telemetry")] public int IdTelemetry { get; set; } [Column("date", TypeName = "timestamp with time zone"), Comment("'2021-10-19 18:23:54+05'")] public DateTime Date { get; set; } [Column("mode"), Comment("Режим САУБ")] public int? Mode { get; set; } + + + [Column("id_user"), Comment("Пользователь САУБ")] + public int? IdUser { get; set; } + + [Column("well_depth"), Comment("Глубина забоя")] public double? WellDepth { get; set; } [Column("bit_depth"), Comment("Положение инструмента")] public double? BitDepth { get; set; } - [Column("block_height"), Comment("Высота талевого блока")] - public double? BlockHeight { get; set; } + [Column("block_position"), Comment("Высота талевого блока")] + public double? BlockPosition { get; set; } + + + [Column("block_position_min"), Comment("Талевый блок. Мин положение")] + public double? BlockPositionMin { get; set; } + + [Column("block_position_max"), Comment("Талевый блок. Макс положение")] + public double? BlockPositionMax { get; set; } + + [Column("block_speed"), Comment("Скорость талевого блока")] public double? BlockSpeed { get; set; } [Column("block_speed_sp"), Comment("Скорости талевого блока. Задание")] public double? BlockSpeedSp { get; set; } + + [Column("block_speed_sp_rotor"), Comment("Талевый блок. Задание скорости для роторного бурения")] + public double? BlockSpeedSpRotor { get; set; } + + [Column("block_speed_sp_slide"), Comment("Талевый блок. Задание скорости для режима слайда")] + public double? BlockSpeedSpSlide { get; set; } + + [Column("block_speed_sp_develop"), Comment("Талевый блок. Задание скорости для проработки")] + public double? BlockSpeedSpDevelop { get; set; } + [Column("pressure"), Comment("Давление")] public double? Pressure { get; set; } [Column("pressure_idle"), Comment("Давление. Холостой ход")] public double? PressureIdle { get; set; } [Column("pressure_sp"), Comment("Давление. Задание")] public double? PressureSp { get; set; } + + [Column("pressure_sp_rotor"), Comment("Давление. Задание для роторного бурения")] + public double? PressureSpRotor { get; set; } + + + [Column("pressure_sp_slide"), Comment("Давление. Задание для режима слайда")] + public double? PressureSpSlide { get; set; } + + [Column("pressure_sp_develop"), Comment("Давление. Задание для проработки")] + public double? PressureSpDevelop { get; set; } + + [Column("pressure_delta_limit_max"), Comment("Давление дифф. Аварийное макс.")] public double? PressureDeltaLimitMax { get; set; } [Column("axial_load"), Comment("Осевая нагрузка")] diff --git a/AsbCloudDb/Model/Deposit.cs b/AsbCloudDb/Model/Deposit.cs index 9b142838..61e159e8 100644 --- a/AsbCloudDb/Model/Deposit.cs +++ b/AsbCloudDb/Model/Deposit.cs @@ -8,7 +8,7 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_deposit"), Comment("Месторождение")] - public partial class Deposit: IId + public partial class Deposit : IId { public Deposit() { diff --git a/AsbCloudDb/Model/Event.cs b/AsbCloudDb/Model/Event.cs index 85fcc17d..8f708aec 100644 --- a/AsbCloudDb/Model/Event.cs +++ b/AsbCloudDb/Model/Event.cs @@ -1,25 +1,35 @@ using Microsoft.EntityFrameworkCore; -using System; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; #nullable disable namespace AsbCloudDb.Model { - [Keyless] [Table("t_event"), Comment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии.")] - [Index(nameof(IdEvent), nameof(Version), Name = "t_event_pk", IsUnique = true)] public partial class Event { [Column("id_event")] - public int? IdEvent { get; set; } - [Column("version"), Comment("Версия ПО отправляющей телеметрии.")] - [StringLength(64)] - public string Version { get; set; } + public int IdEvent { get; set; } + + [Column("id_telemetry")] + public int IdTelemetry { get; set; } + + [JsonIgnore] + [ForeignKey(nameof(IdTelemetry))] + [InverseProperty(nameof(Model.Telemetry.Events))] + public virtual Telemetry Telemetry { get; set; } + [Column("id_category")] - public int? IdCategory { get; set; } + public int IdCategory { get; set; } + [Column("message_template")] public string MessageTemplate { get; set; } + + public string MakeMessageText(Message message) + { + var args = new string[] { message.Arg0, message.Arg1, message.Arg2, message.Arg3 }; + return string.Format(MessageTemplate, args); + } } } diff --git a/AsbCloudDb/Model/IId.cs b/AsbCloudDb/Model/IId.cs index 6aa063e7..0dda384d 100644 --- a/AsbCloudDb/Model/IId.cs +++ b/AsbCloudDb/Model/IId.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace AsbCloudDb.Model +namespace AsbCloudDb.Model { public interface IId { diff --git a/AsbCloudDb/Model/Message.cs b/AsbCloudDb/Model/Message.cs index be5e7bb1..d263b26a 100644 --- a/AsbCloudDb/Model/Message.cs +++ b/AsbCloudDb/Model/Message.cs @@ -8,33 +8,42 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_message"), Comment("Сообщения на буровых")] - public partial class Message: IId + public partial class Message : IId { [Key] [Column("id")] public int Id { get; set; } + [Column("id_telemetry")] public int? IdTelemetry { get; set; } + [Column("id_event")] public int IdEvent { get; set; } + [Column("id_telemetry_user"), Comment("Пользователь панели отправляющей телеметрию. не пользователь облака.")] public int? IdTelemetryUser { get; set; } + [Column("date", TypeName = "timestamp with time zone")] public DateTime Date { get; set; } + [Column("state"), Comment("1 - сработало событие. 0 - событие пропало.")] public int? State { get; set; } + [Column("arg0"), Comment("Аргумент №0 для вставки в шаблон сообщения")] [StringLength(255)] public string Arg0 { get; set; } + [Column("arg1")] [StringLength(255)] public string Arg1 { get; set; } + + [Column("arg2")] + [StringLength(255)] + public string Arg2 { get; set; } + [Column("arg3")] [StringLength(255)] public string Arg3 { get; set; } - [Column("arg4")] - [StringLength(255)] - public string Arg4 { get; set; } [ForeignKey(nameof(IdTelemetry))] [InverseProperty(nameof(Model.Telemetry.Messages))] diff --git a/AsbCloudDb/Model/Telemetry.cs b/AsbCloudDb/Model/Telemetry.cs index ac39dafe..5c6f7e59 100644 --- a/AsbCloudDb/Model/Telemetry.cs +++ b/AsbCloudDb/Model/Telemetry.cs @@ -10,8 +10,7 @@ namespace AsbCloudDb.Model { [Table("t_telemetry"), Comment("таблица привязки телеметрии от комплектов к конкретной скважине.")] [Index(nameof(RemoteUid), Name = "t_telemetry_remote_uid_index")] - [Index(nameof(Version), Name = "t_telemetry_version_index")] - public partial class Telemetry: IId + public partial class Telemetry : IId { public Telemetry() { @@ -23,21 +22,11 @@ namespace AsbCloudDb.Model [Column("id")] public int Id { get; set; } - [Column("remote_uid"), Comment("Идентификатор передающего устройства. Может посторяться в списке, так как комплекты оборудования переезжают от скв. к скв.")] + [Column("remote_uid"), Comment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.")] public string RemoteUid { get; set; } [Column("info", TypeName = "jsonb"), Comment("Информация с панели о скважине")] - public string Info { get; set; } - - [Column("version"), Comment("Версия ПО панели отправляющей телеметрию")] - [StringLength(64)] - public string Version { get; set; } - - [Column("last_data_saub", TypeName = "jsonb"), Comment("Информация с панели о скважине")] - public DataSaubBase LastDataSaub { get; set; } - - [Column("time_zone", TypeName = "json"), Comment("Временная зона панели САУБ.")] - public TimeZoneInfo TimeZone { get; set; } + public TelemetryInfo Info { get; set; } [InverseProperty(nameof(Model.Well.Telemetry))] public virtual Well Well { get; set; } @@ -47,5 +36,12 @@ namespace AsbCloudDb.Model [InverseProperty(nameof(Message.Telemetry))] public virtual ICollection Messages { get; set; } + + [InverseProperty(nameof(TelemetryUser.Telemetry))] + public virtual ICollection Users { get; set; } + + [InverseProperty(nameof(Event.Telemetry))] + public virtual ICollection Events { get; set; } + } } diff --git a/AsbCloudDb/Model/TelemetryInfo.cs b/AsbCloudDb/Model/TelemetryInfo.cs new file mode 100644 index 00000000..9a592443 --- /dev/null +++ b/AsbCloudDb/Model/TelemetryInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AsbCloudDb.Model +{ + public class TelemetryInfo + { + public DateTime Date { get; set; } + public string TimeZoneId { get; set; } + public double TimeZoneOffsetTotalHours { get; set; } + public string Caption { get; set; } + public string Cluster { get; set; } + public string Deposit { get; set; } + public string HmiVersion { get; set; } + public string PlcVersion { get; set; } + public string Comment { get; set; } + } +} diff --git a/AsbCloudDb/Model/TelemetryUser.cs b/AsbCloudDb/Model/TelemetryUser.cs index 4d6d8dd7..7aa228ed 100644 --- a/AsbCloudDb/Model/TelemetryUser.cs +++ b/AsbCloudDb/Model/TelemetryUser.cs @@ -1,34 +1,58 @@ using Microsoft.EntityFrameworkCore; -using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; #nullable disable namespace AsbCloudDb.Model { - [Keyless] [Table("t_telemetry_user"), Comment("Пользователи панели САУБ. Для сообщений.")] - [Index(nameof(IdUser), nameof(IdTelemetry), Name = "t_telemetry_user_pk", IsUnique = true)] public partial class TelemetryUser { [Column("id_user")] public int IdUser { get; set; } + [Column("id_telemetry")] public int IdTelemetry { get; set; } + + + [JsonIgnore] + [ForeignKey(nameof(IdTelemetry))] + [InverseProperty(nameof(Model.Telemetry.Users))] + public virtual Telemetry Telemetry { get; set; } + [Column("name")] [StringLength(255)] public string Name { get; set; } + [Column("surname")] [StringLength(255)] public string Surname { get; set; } + [Column("patronymic")] [StringLength(255)] public string Patronymic { get; set; } + [Column("level")] public int? Level { get; set; } - [ForeignKey(nameof(IdTelemetry))] - public virtual Telemetry Telemetry { get; set; } + + public string MakeDisplayName() + { + if (!string.IsNullOrEmpty(Surname)) + { + var s = Surname; + if (!string.IsNullOrEmpty(Name)) + { + s += $"{Name[0]}."; + if (!string.IsNullOrEmpty(Patronymic)) + s += $" {Patronymic[0]}."; + } + return s; + } + else + return $"User #{IdTelemetry}"; + } } } diff --git a/AsbCloudDb/Model/User.cs b/AsbCloudDb/Model/User.cs index df50f382..3108aa44 100644 --- a/AsbCloudDb/Model/User.cs +++ b/AsbCloudDb/Model/User.cs @@ -7,7 +7,7 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_user"), Comment("Пользователи облака")] - public partial class User: IId + public partial class User : IId { [Key] [Column("id")] @@ -34,15 +34,15 @@ namespace AsbCloudDb.Model [Column("level")] public int? Level { get; set; } - [Column("name")] + [Column("name"), Comment("имя")] [StringLength(255)] public string Name { get; set; } - [Column("surname")] + [Column("surname"), Comment("фамилия")] [StringLength(255)] public string Surname { get; set; } - [Column("patronymic")] + [Column("patronymic"), Comment("отчество")] [StringLength(255)] public string Patronymic { get; set; } @@ -53,5 +53,21 @@ namespace AsbCloudDb.Model [ForeignKey(nameof(IdRole))] [InverseProperty(nameof(Model.UserRole.Users))] public virtual UserRole Role { get; set; } + + public string MakeDisplayName() + { + if (string.IsNullOrEmpty(Surname)) + return Login; + + var s = Surname; + if (!string.IsNullOrEmpty(Name)) + { + s += $"{Name[0]}."; + if (!string.IsNullOrEmpty(Patronymic)) + s += $" {Patronymic[0]}."; + } + + return s; + } } } diff --git a/AsbCloudDb/Model/Well.cs b/AsbCloudDb/Model/Well.cs index d8a9507f..8d30880a 100644 --- a/AsbCloudDb/Model/Well.cs +++ b/AsbCloudDb/Model/Well.cs @@ -7,7 +7,7 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_well"), Comment("скважины")] - public partial class Well: IId + public partial class Well : IId { [Key] [Column("id")] diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 1772ff7c..63982103 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -25,7 +25,10 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); return services; } @@ -34,6 +37,12 @@ namespace AsbCloudInfrastructure { cfg.CreateMap(); cfg.CreateMap(); + + cfg.CreateMap(); + cfg.CreateMap(); + + cfg.CreateMap(); + cfg.CreateMap(); } } } diff --git a/AsbCloudInfrastructure/Services/AuthService.cs b/AsbCloudInfrastructure/Services/AuthService.cs index 6bcd9739..da136f92 100644 --- a/AsbCloudInfrastructure/Services/AuthService.cs +++ b/AsbCloudInfrastructure/Services/AuthService.cs @@ -52,7 +52,7 @@ namespace AsbCloudInfrastructure.Services RoleName = identity.User.Role.Caption, Surname = identity.User.Surname, Token = MakeToken(identity.Identity.Claims), - }; + }; } public string Refresh(ClaimsPrincipal user) diff --git a/AsbCloudInfrastructure/Services/Cache/CacheDb.cs b/AsbCloudInfrastructure/Services/Cache/CacheDb.cs index babe3363..cb51a225 100644 --- a/AsbCloudInfrastructure/Services/Cache/CacheDb.cs +++ b/AsbCloudInfrastructure/Services/Cache/CacheDb.cs @@ -1,16 +1,13 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Internal; -using System; -using System.Collections.Generic; using System.Collections.Concurrent; -using System.Text; +using System.Collections.Generic; namespace AsbCloudInfrastructure.Services.Cache { public class CacheDb - { - private ConcurrentDictionary> cache = new ConcurrentDictionary>(); + { + private readonly ConcurrentDictionary> cache = new ConcurrentDictionary>(); public ICacheTable GetCachedTable(DbContext context) where TEntity : class @@ -24,7 +21,7 @@ namespace AsbCloudInfrastructure.Services.Cache return tableCache; } - public void DropAll()=> cache.Clear(); + public void DropAll() => cache.Clear(); public void Drop() => cache.Remove(typeof(TEntity).FullName, out _); } diff --git a/AsbCloudInfrastructure/Services/Cache/CacheTable.cs b/AsbCloudInfrastructure/Services/Cache/CacheTable.cs index a8e19ba4..0e1b0e43 100644 --- a/AsbCloudInfrastructure/Services/Cache/CacheTable.cs +++ b/AsbCloudInfrastructure/Services/Cache/CacheTable.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -11,31 +10,30 @@ namespace AsbCloudInfrastructure.Services.Cache class CacheTable : ICacheTable where TEntity : class { private readonly DbContext context; - private List entities; + private readonly List cached; internal CacheTable(DbContext context, List entities) { this.context = context; - this.entities = entities; + this.cached = entities; } - public TEntity this[int index] { get => entities.ElementAt(index); } - + public TEntity this[int index] { get => cached.ElementAt(index); } public int Refresh() { - entities.Clear(); + cached.Clear(); var dbEntities = context.Set().ToList(); - entities.AddRange(dbEntities); - return entities.Count(); + cached.AddRange(dbEntities); + return cached.Count(); } public async Task RefreshAsync(CancellationToken token = default) { - entities.Clear(); + cached.Clear(); var dbEntities = await context.Set().ToListAsync(token).ConfigureAwait(false); - entities.AddRange(dbEntities); - return entities.Count(); + cached.AddRange(dbEntities); + return cached.Count(); } private bool CheckRefresh(RefreshMode refreshMode) @@ -46,7 +44,7 @@ namespace AsbCloudInfrastructure.Services.Cache return true; } - if ((!entities.Any()) && (refreshMode == RefreshMode.IfResultEmpty)) + if ((!cached.Any()) && (refreshMode == RefreshMode.IfResultEmpty)) { Refresh(); return true; @@ -63,7 +61,7 @@ namespace AsbCloudInfrastructure.Services.Cache return true; } - if ((!entities.Any()) && (refreshMode == RefreshMode.IfResultEmpty)) + if ((!cached.Any()) && (refreshMode == RefreshMode.IfResultEmpty)) { await RefreshAsync(token); return true; @@ -88,12 +86,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = CheckRefresh(refreshMode); - var result = entities.FirstOrDefault(); + var result = cached.FirstOrDefault(); if (result == default && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { Refresh(); - return entities.FirstOrDefault(); + return cached.FirstOrDefault(); } return result; @@ -103,12 +101,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = await CheckRefreshAsync(refreshMode, token); - var result = entities.FirstOrDefault(); + var result = cached.FirstOrDefault(); if (result == default && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { await RefreshAsync(token); - return entities.FirstOrDefault(); + return cached.FirstOrDefault(); } return result; @@ -121,12 +119,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = CheckRefresh(refreshMode); - var result = entities.FirstOrDefault(predicate); + var result = cached.FirstOrDefault(predicate); if (result == default && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { Refresh(); - return entities.FirstOrDefault(predicate); + return cached.FirstOrDefault(predicate); } return result; @@ -136,12 +134,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = await CheckRefreshAsync(refreshMode, token); - var result = entities.FirstOrDefault(predicate); + var result = cached.FirstOrDefault(predicate); if (result == default && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { await RefreshAsync(token); - return entities.FirstOrDefault(predicate); + return cached.FirstOrDefault(predicate); } return result; @@ -154,12 +152,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = CheckRefresh(refreshMode); - var result = entities.Where(predicate); + var result = cached.Where(predicate); if (!result.Any() && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { Refresh(); - return entities.Where(predicate); + return cached.Where(predicate); } return result; @@ -169,12 +167,12 @@ namespace AsbCloudInfrastructure.Services.Cache { bool isUpdated = await CheckRefreshAsync(refreshMode, token); - var result = entities.Where(predicate); + var result = cached.Where(predicate); if (!result.Any() && refreshMode == RefreshMode.IfResultEmpty && !isUpdated) { await RefreshAsync(token); - return entities.Where(predicate); + return cached.Where(predicate); } return result; @@ -190,8 +188,8 @@ namespace AsbCloudInfrastructure.Services.Cache mutation(dbEntity); context.SaveChanges(); } - entities.RemoveAll(e => predicate(e)); - entities.AddRange(dbEntities); + cached.RemoveAll(e => predicate(e)); + cached.AddRange(dbEntities); return dbEntities; } @@ -205,15 +203,117 @@ namespace AsbCloudInfrastructure.Services.Cache mutation(dbEntity); await context.SaveChangesAsync(token).ConfigureAwait(false); } - entities.RemoveAll(e => predicate(e)); - entities.AddRange(dbEntities); + cached.RemoveAll(e => predicate(e)); + cached.AddRange(dbEntities); return dbEntities; } + public TEntity Upsert(TEntity entity) + { + var dbSet = context.Set(); + Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entityEntry; + if (cached.Contains(entity)) + { + entityEntry = dbSet.Update(entity); + cached.Remove(entity); + } + else + { + entityEntry = dbSet.Add(entity); + } + + context.SaveChanges(); + + cached.Add(entityEntry.Entity); + + return entityEntry.Entity; + } + + + + public async Task UpsertAsync(TEntity entity, CancellationToken token = default) + { + var dbSet = context.Set(); + Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entityEntry; + + if (cached.Contains(entity)) + { + entityEntry = dbSet.Update(entity); + cached.Remove(entity); + } + else + { + entityEntry = dbSet.Add(entity); + } + + await context.SaveChangesAsync(token).ConfigureAwait(false); + + cached.Add(entityEntry.Entity); + + return entityEntry.Entity; + } + + public IEnumerable Upsert(IEnumerable entities) + { + var dbSet = context.Set(); + + var upsertedEntries = new List>(entities.Count()); + foreach (var entity in entities) + { + Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entityEntry; + if (cached.Contains(entity)) + { + entityEntry = dbSet.Update(entity); + cached.Remove(entity); + } + else + { + entityEntry = dbSet.Add(entity); + } + upsertedEntries.Add(entityEntry); + } + + context.SaveChanges(); + + var upserted = upsertedEntries.Select(e => e.Entity); + + cached.AddRange(upserted); + + return upserted; + } + + public async Task> UpsertAsync(IEnumerable entities, CancellationToken token = default) + { + var dbSet = context.Set(); + + var upsertedEntries = new List>(entities.Count()); + foreach (var entity in entities) + { + Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entityEntry; + if (cached.Contains(entity)) + { + entityEntry = dbSet.Update(entity); + cached.Remove(entity); + } + else + { + entityEntry = dbSet.Add(entity); + } + upsertedEntries.Add(entityEntry); + } + + await context.SaveChangesAsync(token).ConfigureAwait(false); + + var upserted = upsertedEntries.Select(e => e.Entity); + + cached.AddRange(upserted); + + return upserted; + } public void Remove(Func predicate) { var dbSet = context.Set(); - entities.RemoveAll(e => predicate(e)); + cached.RemoveAll(e => predicate(e)); dbSet.RemoveRange(dbSet.Where(predicate)); context.SaveChanges(); return; @@ -222,7 +322,7 @@ namespace AsbCloudInfrastructure.Services.Cache public async Task RemoveAsync(Func predicate, CancellationToken token = default) { var dbSet = context.Set(); - entities.RemoveAll(e => predicate(e)); + cached.RemoveAll(e => predicate(e)); dbSet.RemoveRange(dbSet.Where(predicate)); await context.SaveChangesAsync(token).ConfigureAwait(false); return; @@ -233,7 +333,7 @@ namespace AsbCloudInfrastructure.Services.Cache var dbSet = context.Set(); var dbEntity = dbSet.Add(entity).Entity; context.SaveChanges(); - entities.Add(dbEntity); + cached.Add(dbEntity); return dbEntity; } @@ -242,7 +342,7 @@ namespace AsbCloudInfrastructure.Services.Cache var dbSet = context.Set(); var dbEntity = dbSet.Add(entity).Entity; await context.SaveChangesAsync(token).ConfigureAwait(false); - entities.Add(dbEntity); + cached.Add(dbEntity); return dbEntity; } @@ -253,7 +353,7 @@ namespace AsbCloudInfrastructure.Services.Cache foreach (var item in newEntities) dbEntities.Add(dbSet.Add(item).Entity); context.SaveChanges(); - entities.AddRange(dbEntities); + cached.AddRange(dbEntities); return dbEntities; } @@ -264,7 +364,7 @@ namespace AsbCloudInfrastructure.Services.Cache foreach (var item in newEntities) dbEntities.Add(dbSet.Add(item).Entity); await context.SaveChangesAsync(token).ConfigureAwait(false); - entities.AddRange(dbEntities); + cached.AddRange(dbEntities); return dbEntities; } diff --git a/AsbCloudInfrastructure/Services/Cache/ICacheTable.cs b/AsbCloudInfrastructure/Services/Cache/ICacheTable.cs index 2e04e36e..f7439906 100644 --- a/AsbCloudInfrastructure/Services/Cache/ICacheTable.cs +++ b/AsbCloudInfrastructure/Services/Cache/ICacheTable.cs @@ -17,6 +17,8 @@ namespace AsbCloudInfrastructure.Services.Cache void Remove(Func predicate); IEnumerable Select(Func predicate, RefreshMode refreshMode = RefreshMode.IfResultEmpty); IEnumerable Update(Func predicate, Action mutation); + TEntity Upsert(TEntity entity); + IEnumerable Upsert(IEnumerable entities); //----- ASYNC ------ @@ -33,5 +35,7 @@ namespace AsbCloudInfrastructure.Services.Cache Task> SelectAsync(Func predicate, CancellationToken token = default); Task> SelectAsync(Func predicate, RefreshMode refreshMode = RefreshMode.IfResultEmpty, CancellationToken token = default); Task> UpdateAsync(Func predicate, Action mutation, CancellationToken token = default); + Task UpsertAsync(TEntity entity, CancellationToken token = default); + Task> UpsertAsync(IEnumerable entities, CancellationToken token = default); } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/TelemetryDataService.cs b/AsbCloudInfrastructure/Services/DataService.cs similarity index 63% rename from AsbCloudInfrastructure/Services/TelemetryDataService.cs rename to AsbCloudInfrastructure/Services/DataService.cs index da5a3015..089dcf9e 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataService.cs +++ b/AsbCloudInfrastructure/Services/DataService.cs @@ -6,20 +6,21 @@ using AutoMapper; using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { - public class TelemetryDataService : ITelemetryDataService + public class DataService : IDataService { - private IAsbCloudDbContext db; - private IMapper mapper; - private ICacheTable cacheTelemetry; - private ICacheTable cacheWells; + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + private readonly IMapper mapper; + private readonly ICacheTable cacheTelemetry; + private readonly ICacheTable cacheWells; - public TelemetryDataService(IAsbCloudDbContext db, CacheDb cacheDb, MapperConfiguration mapperConfiguration) + public DataService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb, MapperConfiguration mapperConfiguration) { this.db = db; + this.telemetryService = telemetryService; mapper = mapperConfiguration.CreateMapper(); cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); @@ -30,12 +31,12 @@ namespace AsbCloudInfrastructure.Services var well = cacheWells.FirstOrDefault(w => w.Id == wellId); if (well is null) return default; - + var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == well.IdTelemetry); if (telemetry is null) return default; - if(dateBegin == default) + if (dateBegin == default) dateBegin = DateTime.Now.AddSeconds(-intervalSec); var datEnd = dateBegin.AddSeconds(intervalSec); @@ -58,11 +59,29 @@ namespace AsbCloudInfrastructure.Services var dbData = fullData.ToList(); var result = new List(dbData.Count); - + foreach (var item in dbData) result.Add(mapper.Map(item)); return result; } + + public void UpdateData(string uid, IEnumerable dtos) + { + var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); + + if ((dtos != default) && (dtos.Count() > 0)) + { + foreach (var item in dtos) + { + var dataSaub = mapper.Map(item); + dataSaub.IdTelemetry = telemetryId; + db.DataSaubBases.Add(dataSaub); + } + + db.SaveChanges(); + } + } + } } diff --git a/AsbCloudInfrastructure/Services/DepositService.cs b/AsbCloudInfrastructure/Services/DepositService.cs deleted file mode 100644 index 95e9ef38..00000000 --- a/AsbCloudInfrastructure/Services/DepositService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AsbCloudApp.Services; -using AsbCloudDb.Model; -using AutoMapper; - -namespace AsbCloudInfrastructure.Services -{ - public class DepositService : IDepositService - { - private readonly IAsbCloudDbContext db; - private readonly MapperConfiguration mapperConfiguration; - - public DepositService(IAsbCloudDbContext db, MapperConfiguration mapperConfiguration) - { - this.db = db; - this.mapperConfiguration = mapperConfiguration; - } - - } -} diff --git a/AsbCloudInfrastructure/Services/EventService.cs b/AsbCloudInfrastructure/Services/EventService.cs new file mode 100644 index 00000000..0038ed04 --- /dev/null +++ b/AsbCloudInfrastructure/Services/EventService.cs @@ -0,0 +1,56 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services +{ + public class EventService : IEventService + { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + private readonly ICacheTable cacheEvents; + + public EventService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService) + { + this.db = db; + this.telemetryService = telemetryService; + cacheEvents = cacheDb.GetCachedTable((AsbCloudDbContext)db); + } + + public void Upsert(string uid, IEnumerable dtos) + { + if (dtos.Count() == 0) + return; + + var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); + + var ids = dtos.Select(e => e.Id).ToList(); + + var dbIds = (from e in db.Events + where e.IdTelemetry == telemetryId && ids.Contains(e.IdEvent) + select e.IdEvent).ToList(); + + foreach (var dto in dtos) + { + var entity = new Event + { + IdEvent = dto.Id, + IdTelemetry = telemetryId, + IdCategory = dto.IdCategory, + MessageTemplate = dto.Message + }; + + if (dbIds.Contains(dto.Id)) + db.Events.Update(entity); + else + db.Events.Add(entity); + } + + db.SaveChanges(); + cacheEvents.Refresh(); + } + } +} diff --git a/AsbCloudInfrastructure/Services/MessageService.cs b/AsbCloudInfrastructure/Services/MessageService.cs new file mode 100644 index 00000000..e4eed486 --- /dev/null +++ b/AsbCloudInfrastructure/Services/MessageService.cs @@ -0,0 +1,127 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using AutoMapper; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services +{ + public class MessageService : IMessageService + { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + private readonly IMapper mapper; + private readonly ICacheTable cacheEvents; + private readonly ICacheTable cacheTUsers; + private readonly ICacheTable cacheTelemetry; + private readonly ICacheTable cacheWells; + + public MessageService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService, MapperConfiguration mapperConfiguration) + { + this.db = db; + this.telemetryService = telemetryService; + mapper = mapperConfiguration.CreateMapper(); + cacheEvents = cacheDb.GetCachedTable((AsbCloudDbContext)db); + cacheTUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); + cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); + cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); + } + + public PaginationContainer GetMessages(int wellId, IEnumerable categoryids = default, DateTime begin = default, DateTime end = default, int skip = 0, int take = 32) + { + var well = cacheWells.FirstOrDefault(w => w.Id == wellId); + if (well is null) + return null; + + var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == well.Id); + if (telemetry is null) + return null; + + var events = cacheEvents.Select(e => e.IdTelemetry == telemetry.Id); + + if (events.Count() == 0) + return null; + + var messages = from m in db.Messages + where m.IdTelemetry == telemetry.Id + && m.State == 1 + select m; + + if ((categoryids != default) && (categoryids.Count() > 0)) + { + var eventIds = from e in events + where categoryids.ToList().Contains(e.IdCategory) + select e.IdEvent; + + if (eventIds.Count() == 0) + return null; + + messages = messages.Where(m => eventIds.Contains(m.IdEvent)); + } + + var result = new PaginationContainer() { Skip = skip, Take = take}; + + messages = messages.OrderByDescending(m => m.Date); + + if (begin != default) + messages = messages.Where(m => m.Date >= begin); + + if (end != default) + messages = messages.Where(m => m.Date <= end); + + result.Count = messages.Count(); + + if (skip > 0) + messages = messages.Skip(skip); + + var messagesList = messages.Take(take).ToList(); + + if (messagesList.Count == 0) + return result; + + var users = cacheTUsers.Select(u => u.IdTelemetry == telemetry.Id); + + foreach (var message in messagesList) + { + var messageDto = new MessageDto + { + Date = message.Date, + Id = message.Id, + User = users.FirstOrDefault(u => u.IdUser == message.IdTelemetryUser).MakeDisplayName(), + }; + + var e = events.FirstOrDefault(e => e.IdEvent == message.IdEvent); + if (e != null) + { + messageDto.CategoryId = e.IdCategory; + messageDto.Message = e.MakeMessageText(message); + } + + result.Items.Add(messageDto); + } + + return result; + } + + public void Insert(string uid, IEnumerable dtos) + { + if (dtos.Count() == 0) + return; + + var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); + + foreach (var dto in dtos) + { + var entity = mapper.Map(dto); + entity.IdTelemetry = telemetryId; + db.Messages.Add(entity); + } + + db.SaveChanges(); + } + } +} diff --git a/AsbCloudInfrastructure/Services/TelemetryService.cs b/AsbCloudInfrastructure/Services/TelemetryService.cs index 388c2aa9..2eb58845 100644 --- a/AsbCloudInfrastructure/Services/TelemetryService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryService.cs @@ -3,82 +3,47 @@ using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using AutoMapper; -using System.Text.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class TelemetryService : ITelemetryService { - private readonly IAsbCloudDbContext db; private readonly IMapper mapper; private readonly ICacheTable cacheTelemetry; private readonly ICacheTable cacheWell; - public TelemetryService(IAsbCloudDbContext db, CacheDb cacheDb, MapperConfiguration mapperConfiguration) + public TelemetryService(IAsbCloudDbContext db, CacheDb cacheDb, MapperConfiguration mapperConfiguration) { - this.db = db; mapper = mapperConfiguration.CreateMapper(); cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWell = cacheDb.GetCachedTable((AsbCloudDbContext)db); } - public int? GetWellIdByUid(string uid) + public int GetOrCreateTemetryIdByUid(string uid) + => GetOrCreateTelemetryByUid(uid).Id; + + public int? GetWellIdByTelemetryUid(string uid) + => GetWellByTelemetryUid(uid)?.Id; + + public void UpdateInfo(string uid, TelemetryInfoDto info) + { + var telemetry = GetOrCreateTelemetryByUid(uid); + telemetry.Info = mapper.Map(info); + cacheTelemetry.Upsert(telemetry); + } + + private Well GetWellByTelemetryUid(string uid) { var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid, RefreshMode.IfResultEmpty); if (tele is null) return null; - return cacheWell.FirstOrDefault(w => w?.IdTelemetry == tele.Id)?.Id; + return cacheWell.FirstOrDefault(w => w?.IdTelemetry == tele.Id); } - - private Telemetry GetOrCreateTelemetry(string uid) + + private Telemetry GetOrCreateTelemetryByUid(string uid) => cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid, RefreshMode.IfResultEmpty) - ?? cacheTelemetry.Insert(new Telemetry{ RemoteUid = uid, }); + ?? cacheTelemetry.Insert(new Telemetry { RemoteUid = uid, }); - public void UpdateData(string uid, TelemetryDataDto data) - { - var telemetry = GetOrCreateTelemetry(uid); - - if ((data.DataSaub != default) && (data.DataSaub.Count() > 0)) - { - DataSaubBase dataSaub = default; - foreach (var item in data.DataSaub) - { - dataSaub = mapper.Map(item); - dataSaub.IdTelemetry = telemetry.Id; - db.DataSaubBases.Add(dataSaub); - } - - if(dataSaub != default) - telemetry.LastDataSaub = dataSaub; - - db.SaveChanges(); - } - } - - public void UpdateInfo(string uid, TelemetryInfoDto info) - { - var telemetry = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid); - var infoJson = JsonSerializer.Serialize(info); - - //TODO: update telemetry timezone - - if (telemetry is null) - { - var newTelemetry = new Telemetry - { - RemoteUid = uid, - Info = infoJson, - }; - telemetry = cacheTelemetry.Insert(newTelemetry); - } - else - cacheTelemetry.Update(t => t.RemoteUid == uid, t => t.Info = infoJson); - } } } diff --git a/AsbCloudInfrastructure/Services/TelemetryUserService.cs b/AsbCloudInfrastructure/Services/TelemetryUserService.cs new file mode 100644 index 00000000..4b00b936 --- /dev/null +++ b/AsbCloudInfrastructure/Services/TelemetryUserService.cs @@ -0,0 +1,58 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services +{ + public class TelemetryUserService : ITelemetryUserService + { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + private readonly ICacheTable cacheTUsers; + + public TelemetryUserService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService) + { + this.db = db; + this.telemetryService = telemetryService; + cacheTUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); + } + + public void Upsert(string uid, IEnumerable dtos) + { + if (dtos.Count() == 0) + return; + + var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); + + var ids = dtos.Select(e => e.Id).ToList(); + + var dbIds = (from e in db.TelemetryUsers + where e.IdTelemetry == telemetryId && ids.Contains(e.IdUser) + select e.IdUser).ToList(); + + foreach (var dto in dtos) + { + var entity = new TelemetryUser + { + IdUser = dto.Id, + IdTelemetry = telemetryId, + Level = dto.Level, + Name = dto.Name, + Patronymic = dto.Patronymic, + Surname = dto.Surname, + }; + + if (dbIds.Contains(dto.Id)) + db.TelemetryUsers.Update(entity); + else + db.TelemetryUsers.Add(entity); + } + + db.SaveChanges(); + cacheTUsers.Refresh(); + } + } +} diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index 383416bd..feb98403 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -10,12 +10,10 @@ namespace AsbCloudInfrastructure.Services public class WellService : IWellService { private readonly IAsbCloudDbContext db; - private readonly MapperConfiguration mapperConfiguration; - public WellService(IAsbCloudDbContext db, MapperConfiguration mapperConfiguration) + public WellService(IAsbCloudDbContext db) { this.db = db; - this.mapperConfiguration = mapperConfiguration; } public IEnumerable GetWellsByCustomer(int idCustomer) @@ -34,9 +32,6 @@ namespace AsbCloudInfrastructure.Services Deposit = well.Cluster.Deposit.Caption, }; - if (well.Telemetry?.LastDataSaub != default) - wellDto.LastData = mapperConfiguration.CreateMapper().Map(well.Telemetry.LastDataSaub); - return wellDto; } } diff --git a/AsbCloudWebApi/Controllers/AuthController.cs b/AsbCloudWebApi/Controllers/AuthController.cs index db8f7d77..1133e625 100644 --- a/AsbCloudWebApi/Controllers/AuthController.cs +++ b/AsbCloudWebApi/Controllers/AuthController.cs @@ -32,7 +32,7 @@ namespace AsbCloudWebApi.Controllers var userToken = authService.Login(auth.Login, auth.Password); if (userToken is null) BadRequest();//"wrong login or password" - + return Ok(userToken); } diff --git a/AsbCloudWebApi/Controllers/DataController.cs b/AsbCloudWebApi/Controllers/DataController.cs index 6437320b..fe3a0d64 100644 --- a/AsbCloudWebApi/Controllers/DataController.cs +++ b/AsbCloudWebApi/Controllers/DataController.cs @@ -4,8 +4,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers { @@ -17,9 +15,9 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class DataController : ControllerBase { - private readonly ITelemetryDataService telemetryDataService; + private readonly IDataService telemetryDataService; - public DataController(ITelemetryDataService telemetryDataService) + public DataController(IDataService telemetryDataService) { this.telemetryDataService = telemetryDataService; } @@ -38,7 +36,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public IActionResult Get(int wellId, DateTime begin = default, int intervalSec = 600, int approxPointsCount = 1024) { - if(begin == default) + if (begin == default) begin = DateTime.Now.AddSeconds(-intervalSec); var content = telemetryDataService.Get(wellId, begin, intervalSec, approxPointsCount); return Ok(content); diff --git a/AsbCloudWebApi/Controllers/MessageController.cs b/AsbCloudWebApi/Controllers/MessageController.cs new file mode 100644 index 00000000..be3c02ea --- /dev/null +++ b/AsbCloudWebApi/Controllers/MessageController.cs @@ -0,0 +1,45 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; + +namespace AsbCloudWebApi.Controllers +{ + [Route("api/well")] + [ApiController] + public class MessageController : ControllerBase + { + private readonly IMessageService messageService; + + public MessageController(IMessageService messageService) + { + this.messageService = messageService; + } + + /// + /// Выдает список сообщений по скважине + /// + /// id скважины + /// список категорий + /// дата начала + /// окончание + /// для пагинации кол-во записей пропустить + /// для пагинации кол-во записей + /// список сообщений по скважине + [HttpGet] + [Route("{wellId}/message")] + [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] + public IActionResult Get(int wellId, [FromQuery] IEnumerable categoryids = default, DateTime begin = default, DateTime end = default, int skip = 0, int take = 32) + { + if (take > 1024) + return BadRequest("limit mast be less then 1024"); + + if (begin > DateTime.Now) + begin = default; + + var result = messageService.GetMessages(wellId, categoryids, begin, end, skip, take); + return Ok(result); + } + } +} diff --git a/AsbCloudWebApi/Controllers/TelemetryController.cs b/AsbCloudWebApi/Controllers/TelemetryController.cs index 8bf57acb..39a8aa1f 100644 --- a/AsbCloudWebApi/Controllers/TelemetryController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryController.cs @@ -1,10 +1,8 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -18,12 +16,26 @@ namespace AsbCloudWebApi.Controllers [ApiController] public class TelemetryController : ControllerBase { + private readonly IDataService DataService; private readonly ITelemetryService telemetryService; + private readonly IMessageService messageService; + private readonly IEventService eventService; + private readonly ITelemetryUserService telemetryUserService; private readonly IHubContext telemetryHubContext; - public TelemetryController(ITelemetryService telemetryService, IHubContext telemetryHubContext) + public TelemetryController( + ITelemetryService telemetryService, + IDataService DataService, + IMessageService messageService, + IEventService eventService, + ITelemetryUserService telemetryUserService, + IHubContext telemetryHubContext) { + this.DataService = DataService; this.telemetryService = telemetryService; + this.messageService = messageService; + this.eventService = eventService; + this.telemetryUserService = telemetryUserService; this.telemetryHubContext = telemetryHubContext; } @@ -45,21 +57,66 @@ namespace AsbCloudWebApi.Controllers /// Принимает данные от разных систем по скважине /// /// Уникальный идентификатор отправителя - /// Данные + /// Данные /// [HttpPost] [Route("{uid}/data")] - public IActionResult Data(string uid, [FromBody] TelemetryDataDto data) + public IActionResult Data(string uid, [FromBody] IEnumerable dtos) { - telemetryService.UpdateData(uid, data); + var wellId = telemetryService.GetWellIdByTelemetryUid(uid); + DataService.UpdateData(uid, dtos); - var wellId = telemetryService.GetWellIdByUid(uid); + if (wellId != null && dtos.Any()) + Task.Run(() => telemetryHubContext.Clients.Group($"well_{wellId}").SendAsync(nameof(ITelemetryHubClient.ReceiveDataSaub), dtos)); - if (wellId != null && data.DataSaub?.Count > 0) - Task.Run(() => telemetryHubContext.Clients.Group($"well_{wellId}").SendAsync(nameof(ITelemetryHubClient.ReceiveDataSaub), data.DataSaub) ); - return Ok(); } + /// + /// Принимает список новых сообщений от телеметрии + /// + /// Уникальный идентификатор отправителя + /// сообщения + /// + [HttpPost] + [Route("{uid}/message")] + public IActionResult Message(string uid, [FromBody] IEnumerable dtos) + { + var wellId = telemetryService.GetWellIdByTelemetryUid(uid); + messageService.Insert(uid, dtos); + + if (dtos.Any()) + Task.Run(() => telemetryHubContext.Clients.Group($"well_{wellId}").SendAsync(nameof(ITelemetryHubClient.ReceiveMessages), dtos)); + + return Ok(); + } + + /// + /// Принимает справочник событий + /// + /// Уникальный идентификатор отправителя + /// справочник событий + /// + [HttpPost] + [Route("{uid}/event")] + public IActionResult Events(string uid, [FromBody] List events) + { + eventService.Upsert(uid, events); + return Ok(); + } + + /// + /// Принимает справочник пользователей телеметрии + /// + /// Уникальный идентификатор отправителя + /// справочник пользователей телеметрии + /// + [HttpPost] + [Route("{uid}/user")] + public IActionResult Users(string uid, [FromBody] List users) + { + telemetryUserService.Upsert(uid, users); + return Ok(); + } } } diff --git a/AsbCloudWebApi/DependencyInjection.cs b/AsbCloudWebApi/DependencyInjection.cs index 6199143b..9fc7ad1e 100644 --- a/AsbCloudWebApi/DependencyInjection.cs +++ b/AsbCloudWebApi/DependencyInjection.cs @@ -1,6 +1,5 @@ using AsbCloudInfrastructure.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; @@ -21,11 +20,12 @@ namespace AsbCloudWebApi { //c.CustomOperationIds(e => $"{e.ActionDescriptor.RouteValues["controller"]}_{e.HttpMethod}"); //c.CustomOperationIds(e => $"{e.HttpMethod}_{e.ActionDescriptor.Ac"); - c.CustomOperationIds(e=> { + c.CustomOperationIds(e => + { return $"{e.ActionDescriptor.RouteValues["action"]}"; }); - c.SwaggerDoc("v1", new OpenApiInfo { Title = "Charging station", Version = "v1" }); + c.SwaggerDoc("v1", new OpenApiInfo { Title = "ASB cloud web api", Version = "v1" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'", diff --git a/AsbCloudWebApi/SignalR/ITelemetryHubClient.cs b/AsbCloudWebApi/SignalR/ITelemetryHubClient.cs index 83e1f4ee..e566eefb 100644 --- a/AsbCloudWebApi/SignalR/ITelemetryHubClient.cs +++ b/AsbCloudWebApi/SignalR/ITelemetryHubClient.cs @@ -1,13 +1,13 @@ using AsbCloudApp.Data; -using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace AsbCloudWebApi.SignalR { public interface ITelemetryHubClient { - Task ReceiveDataSaub(IEnumerable data); + Task ReceiveDataSaub(IEnumerable dtos); + + Task ReceiveMessages(IEnumerable dtos); } } diff --git a/AsbCloudWebApi/TODO.md b/AsbCloudWebApi/TODO.md index cb546036..8c2f6745 100644 --- a/AsbCloudWebApi/TODO.md +++ b/AsbCloudWebApi/TODO.md @@ -6,7 +6,7 @@ - синхронизация архива телеметрии - +- мониторинг активно передающих скважин - доделать секционирование. - редуцирование архива телеметрии по принципу второй производной. Если вторая производная ~0, то промежуточные значения можно удалить. - редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функиями, сохранять экстремумы и ближайшие к ним значения. diff --git a/AsbCloudWebApi/wwwroot/index.html b/AsbCloudWebApi/wwwroot/index.html index f6b6ceeb..75687662 100644 --- a/AsbCloudWebApi/wwwroot/index.html +++ b/AsbCloudWebApi/wwwroot/index.html @@ -5,6 +5,6 @@ - RAMAMBA! + \ No newline at end of file diff --git a/AsbCloudWebApi/кейсы для админки.txt b/AsbCloudWebApi/кейсы для админки.txt new file mode 100644 index 00000000..ebdccc51 --- /dev/null +++ b/AsbCloudWebApi/кейсы для админки.txt @@ -0,0 +1,6 @@ +Моменты в БД за которыми надо приглядывать. + +Есть t_message для которой нет t_event | Ошибка синхронизации +Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого +2 t_telemetry с не уникальными uid +Провалы в непрерывной t_data. \ No newline at end of file diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index e155756e..8d52f1b9 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,17 +1,11 @@ using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services.Cache; -using AutoMapper; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Running; using Microsoft.EntityFrameworkCore; using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Reflection; namespace ConsoleApp1 { - public class A { + public class A + { public int P1 { get; set; } public int P2 { get; set; } }; @@ -26,10 +20,22 @@ namespace ConsoleApp1 { static void Main(string[] args) { - //var options = new DbContextOptionsBuilder() - // .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") - // .Options; - //var context = new AsbCloudDbContext(options); + var options = new DbContextOptionsBuilder() + .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") + .Options; + var context = new AsbCloudDbContext(options); + + var e = new Event + { + IdEvent = 1, + IdTelemetry = 1, + IdCategory = 1, + MessageTemplate = "template", + }; + + context.Events.Update(e).State = EntityState.Added; + context.SaveChanges(); + //var table = new Table //{ @@ -51,12 +57,12 @@ namespace ConsoleApp1 //var b = new B(); //mapper.UpdateObjectFromTable(ref b, table, 1); - + Console.WriteLine("Done. Press any key to quit."); Console.ReadKey(); } - + } } diff --git a/ConsoleApp1/Table.cs b/ConsoleApp1/Table.cs index 5d76e1ef..01d88410 100644 --- a/ConsoleApp1/Table.cs +++ b/ConsoleApp1/Table.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; namespace ConsoleApp1 { @@ -12,6 +8,6 @@ namespace ConsoleApp1 public IEnumerable> Rows { get; set; } - + } } diff --git a/ConsoleApp1/TableMapper.cs b/ConsoleApp1/TableMapper.cs index 2c03d33f..fd6377c3 100644 --- a/ConsoleApp1/TableMapper.cs +++ b/ConsoleApp1/TableMapper.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Text; -using System.Threading.Tasks; namespace ConsoleApp1 { @@ -22,7 +20,7 @@ namespace ConsoleApp1 var helper = new PropertyHelper(prop); this.props.Add(helper.Id, helper); } - + } public int UpdateObjectFromTable(ref T obj, Table table, int rowIndex) @@ -43,7 +41,7 @@ namespace ConsoleApp1 updatesCount++; } headerIndex++; - } + } return updatesCount; } } @@ -72,7 +70,7 @@ namespace ConsoleApp1 Getter = Expression.Lambda(Expression.Convert(callExpression, typeof(object)), instanceExpression).Compile(); } - public string PropertyName { get;} + public string PropertyName { get; } public Type PropertyType { get; } public string Id { get; } diff --git a/SaubPanelOnlineSender/DbPlayerService.cs b/SaubPanelOnlineSender/DbPlayerService.cs index 1a487495..5d583f10 100644 --- a/SaubPanelOnlineSender/DbPlayerService.cs +++ b/SaubPanelOnlineSender/DbPlayerService.cs @@ -1,7 +1,5 @@ using AsbCloudApp.Data; using System; -using System.Collections.Generic; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -39,7 +37,7 @@ namespace SaubPanelOnlineSender private DbPlayerServiceState state; private static readonly Random rnd = new Random((int)DateTime.Now.Ticks); - + public void Start() { State = DbPlayerServiceState.Working; @@ -109,31 +107,31 @@ namespace SaubPanelOnlineSender return new DataSaubBaseDto { Date = DateTime.Now, - AxialLoad = rnd.NextDouble()*100d, - AxialLoadLimitMax = rnd.NextDouble()*100d, - AxialLoadSp = rnd.NextDouble()*100d, - BitDepth = rnd.NextDouble()*100d, - BlockHeight = rnd.NextDouble()*100d, - BlockSpeed = rnd.NextDouble()*100d, - WellDepth = rnd.NextDouble()*100d, - BlockSpeedSp = rnd.NextDouble()*100d, - Flow = rnd.NextDouble()*100d, - FlowDeltaLimitMax = rnd.NextDouble()*100d, - FlowIdle = rnd.NextDouble()*100d, - HookWeight = rnd.NextDouble()*100d, - HookWeightIdle = rnd.NextDouble()*100d, - HookWeightLimitMax = rnd.NextDouble()*100d, - HookWeightLimitMin= rnd.NextDouble() * 100d, - Mode= 1, - Pressure= rnd.NextDouble() * 100d, - PressureDeltaLimitMax= rnd.NextDouble() * 100d, - PressureIdle= rnd.NextDouble() * 100d, - PressureSp= rnd.NextDouble() * 100d, - RotorSpeed= rnd.NextDouble() * 100d, - RotorTorque= rnd.NextDouble() * 100d, - RotorTorqueIdle= rnd.NextDouble() * 100d, - RotorTorqueLimitMax= rnd.NextDouble() * 100d, - RotorTorqueSp= rnd.NextDouble() * 100d, + AxialLoad = rnd.NextDouble() * 100d, + AxialLoadLimitMax = rnd.NextDouble() * 100d, + AxialLoadSp = rnd.NextDouble() * 100d, + BitDepth = rnd.NextDouble() * 100d, + BlockPosition = rnd.NextDouble() * 100d, + BlockSpeed = rnd.NextDouble() * 100d, + WellDepth = rnd.NextDouble() * 100d, + BlockSpeedSp = rnd.NextDouble() * 100d, + Flow = rnd.NextDouble() * 100d, + FlowDeltaLimitMax = rnd.NextDouble() * 100d, + FlowIdle = rnd.NextDouble() * 100d, + HookWeight = rnd.NextDouble() * 100d, + HookWeightIdle = rnd.NextDouble() * 100d, + HookWeightLimitMax = rnd.NextDouble() * 100d, + HookWeightLimitMin = rnd.NextDouble() * 100d, + Mode = 1, + Pressure = rnd.NextDouble() * 100d, + PressureDeltaLimitMax = rnd.NextDouble() * 100d, + PressureIdle = rnd.NextDouble() * 100d, + PressureSp = rnd.NextDouble() * 100d, + RotorSpeed = rnd.NextDouble() * 100d, + RotorTorque = rnd.NextDouble() * 100d, + RotorTorqueIdle = rnd.NextDouble() * 100d, + RotorTorqueLimitMax = rnd.NextDouble() * 100d, + RotorTorqueSp = rnd.NextDouble() * 100d, }; } } diff --git a/SyncDicts/Program.cs b/SyncDicts/Program.cs new file mode 100644 index 00000000..272b7c30 --- /dev/null +++ b/SyncDicts/Program.cs @@ -0,0 +1,112 @@ +using AsbCloudApp.Data; +using AsbSaubDbModel.V3; +using System; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.Json; + +namespace SyncDicts +{ + class Program + { + /// + /// Описывает процесс синхронизации словарей БД + /// + /// + static void Main(/*string[] args*/) + { + bool res; + var context = new ArchiveDbContext(@"c:\temp\default.sqlite3"); + + // sync Events + var events = context.EventsDictionary.ToList() + .Select(e => new EventDto + { + EventType = e.EventType, + Id = e.Id, + IdCategory = e.CategoryId, + IdSound = e.SoundId, + Message = e.MessageTemplate, + Tag = e.Tag, + }); + + var info = new TelemetryInfoDto + { + Caption = "скв 32", + Deposit = "мр 2", + Cluster = "куст 22", + TimeZoneId = TimeZoneInfo.Local.Id, + TimeZoneOffsetTotalHours = TimeZoneInfo.Local.BaseUtcOffset.TotalHours, + Date = DateTime.Now, + }; + + var users = context.Users.ToList() + .Select(u => new TelemetryUserDto + { + Id = u.Id, + Level = u.Level, + Name = u.Name, + Patronymic = u.Patronymic, + Surname = u.Surname, + }); + + var messages = context.Messages.Take(1024).ToList() + .Select(m => new TelemetryMessageDto + { + Id = m.Id, + Date = DateTime.UnixEpoch.AddSeconds(m.TimeStamp), + IdEvent = m.EventItemId, + IdTelemetryUser = m.UserId, + State = m.State, + Arg0 = m.Arg0, + Arg1 = m.Arg1, + Arg2 = m.Arg2, + Arg3 = m.Arg3, + }); + + //res = Send("http://127.0.0.1:5000/api/telemetry/asdasd/event", events); + //res = Send("http://127.0.0.1:5000/api/telemetry/asdasd/info", info); + //res = Send("http://127.0.0.1:5000/api/telemetry/asdasd/user", users); + res = Send("http://127.0.0.1:5000/api/telemetry/asdasd/message", messages); + } + + private static bool Send(string url, T obj) + { + // sending data + var requestBodyJson = JsonSerializer.Serialize(obj); + var data = Encoding.UTF8.GetBytes(requestBodyJson); + + var request = MakeRequest(url); + using var streamWriter = request.GetRequestStream(); + streamWriter.Write(data); + streamWriter.Close(); + + // getting response + if (request.GetResponse() is not HttpWebResponse response) + {//FAILED + return false; + } + + if (response.StatusCode == HttpStatusCode.OK) + {// sent succesfilly + return true; + } + else + {//failed + return false; + } + } + + private static HttpWebRequest MakeRequest(string url, string contentType = "application/json") + { + var request = WebRequest.CreateHttp(url); + request.Method = "POST"; + request.Timeout = 4900; + request.ContentType = contentType; + request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; + request.ServicePoint.Expect100Continue = false; + return request; + } + } +} diff --git a/SyncDicts/SyncDicts.csproj b/SyncDicts/SyncDicts.csproj new file mode 100644 index 00000000..07f869ed --- /dev/null +++ b/SyncDicts/SyncDicts.csproj @@ -0,0 +1,23 @@ + + + + Exe + net5.0 + + + + + + + + + + + + + + ..\..\..\SAUB\asbsaub3\AsbSaubDbModel\bin\Release\netcoreapp3.1\AsbSaubDbModel.dll + + + + diff --git a/swagger.json b/swagger.json new file mode 100644 index 00000000..8e7cb71a --- /dev/null +++ b/swagger.json @@ -0,0 +1,1022 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "AsbCloudWebApi", + "version": "1.0" + }, + "paths": { + "/auth/login": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Аутентификация пользователя", + "operationId": "Login", + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthDto" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/AuthDto" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/AuthDto" + } + } + } + }, + "responses": { + "200": { + "description": "новый токен", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UserTokenDto" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserTokenDto" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserTokenDto" + } + } + } + }, + "400": { + "description": "логин и пароль не подходят" + } + } + } + }, + "/auth/refresh": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Продление срока действия токена", + "operationId": "Refresh", + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/well/{wellId}/data": { + "get": { + "tags": [ + "Data" + ], + "summary": "Возвращает данные САУБ по скважине.\r\nПо умолчанию за последние 10 минут.", + "operationId": "Get", + "parameters": [ + { + "name": "wellId", + "in": "path", + "description": "id скважины", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "begin", + "in": "query", + "description": "дата начала выборки. По умолчанию: текущее время - intervalSec", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "intervalSec", + "in": "query", + "description": "интервал времени даты начала выборки, секунды", + "schema": { + "type": "integer", + "format": "int32", + "default": 600 + } + }, + { + "name": "approxPointsCount", + "in": "query", + "description": "желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1024 + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + }, + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + } + } + } + } + } + }, + "/api/well/{wellId}/message": { + "get": { + "tags": [ + "Message" + ], + "summary": "Выдает список сообщений по скважине", + "operationId": "Get", + "parameters": [ + { + "name": "wellId", + "in": "path", + "description": "id скважины", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "categoryids", + "in": "query", + "description": "список категорий", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + }, + { + "name": "begin", + "in": "query", + "description": "дата начала", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end", + "in": "query", + "description": "окончание", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "skip", + "in": "query", + "description": "для пагинации кол-во записей пропустить", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "take", + "in": "query", + "description": "для пагинации кол-во записей", + "schema": { + "type": "integer", + "format": "int32", + "default": 32 + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/MessageDtoPaginationContainer" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageDtoPaginationContainer" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/MessageDtoPaginationContainer" + } + } + } + } + } + } + }, + "/api/telemetry/{uid}/info": { + "post": { + "tags": [ + "Telemetry" + ], + "summary": "Принимает общую информацию по скважине", + "operationId": "Info", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Уникальный идентификатор отправителя", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "нформация об отправителе", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryInfoDto" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryInfoDto" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/TelemetryInfoDto" + } + } + } + }, + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/telemetry/{uid}/data": { + "post": { + "tags": [ + "Telemetry" + ], + "summary": "Принимает данные от разных систем по скважине", + "operationId": "Data", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Уникальный идентификатор отправителя", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Данные", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + }, + "application/*+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataSaubBaseDto" + } + } + } + } + }, + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/telemetry/{uid}/message": { + "post": { + "tags": [ + "Telemetry" + ], + "summary": "Принимает список новых сообщений от телеметрии", + "operationId": "Message", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Уникальный идентификатор отправителя", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "сообщения", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryMessageDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryMessageDto" + } + } + }, + "application/*+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryMessageDto" + } + } + } + } + }, + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/telemetry/{uid}/event": { + "post": { + "tags": [ + "Telemetry" + ], + "summary": "Принимает справочник событий", + "operationId": "Events", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Уникальный идентификатор отправителя", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "справочник событий", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventDto" + } + } + }, + "application/*+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventDto" + } + } + } + } + }, + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/telemetry/{uid}/user": { + "post": { + "tags": [ + "Telemetry" + ], + "summary": "Принимает справочник пользователей телеметрии", + "operationId": "Users", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Уникальный идентификатор отправителя", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "справочник пользователей телеметрии", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryUserDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryUserDto" + } + } + }, + "application/*+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryUserDto" + } + } + } + } + }, + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/well": { + "get": { + "tags": [ + "Well" + ], + "operationId": "Get", + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WellDto" + } + } + }, + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WellDto" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WellDto" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AuthDto": { + "type": "object", + "properties": { + "login": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "DataSaubBaseDto": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "mode": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "user": { + "type": "string", + "nullable": true + }, + "wellDepth": { + "type": "number", + "format": "double", + "nullable": true + }, + "bitDepth": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockPosition": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockPositionMin": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockPositionMax": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockSpeed": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockSpeedSp": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockSpeedSpRotor": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockSpeedSpSlide": { + "type": "number", + "format": "double", + "nullable": true + }, + "blockSpeedSpDevelop": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressure": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureIdle": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureSp": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureSpRotor": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureSpSlide": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureSpDevelop": { + "type": "number", + "format": "double", + "nullable": true + }, + "pressureDeltaLimitMax": { + "type": "number", + "format": "double", + "nullable": true + }, + "axialLoad": { + "type": "number", + "format": "double", + "nullable": true + }, + "axialLoadSp": { + "type": "number", + "format": "double", + "nullable": true + }, + "axialLoadLimitMax": { + "type": "number", + "format": "double", + "nullable": true + }, + "hookWeight": { + "type": "number", + "format": "double", + "nullable": true + }, + "hookWeightIdle": { + "type": "number", + "format": "double", + "nullable": true + }, + "hookWeightLimitMin": { + "type": "number", + "format": "double", + "nullable": true + }, + "hookWeightLimitMax": { + "type": "number", + "format": "double", + "nullable": true + }, + "rotorTorque": { + "type": "number", + "format": "double", + "nullable": true + }, + "rotorTorqueIdle": { + "type": "number", + "format": "double", + "nullable": true + }, + "rotorTorqueSp": { + "type": "number", + "format": "double", + "nullable": true + }, + "rotorTorqueLimitMax": { + "type": "number", + "format": "double", + "nullable": true + }, + "rotorSpeed": { + "type": "number", + "format": "double", + "nullable": true + }, + "flow": { + "type": "number", + "format": "double", + "nullable": true + }, + "flowIdle": { + "type": "number", + "format": "double", + "nullable": true + }, + "flowDeltaLimitMax": { + "type": "number", + "format": "double", + "nullable": true + } + }, + "additionalProperties": false + }, + "EventDto": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string", + "nullable": true + }, + "idCategory": { + "type": "integer", + "format": "int32" + }, + "tag": { + "type": "string", + "nullable": true + }, + "eventType": { + "type": "integer", + "format": "int32" + }, + "idSound": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "MessageDto": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "categoryId": { + "type": "integer", + "format": "int32" + }, + "user": { + "type": "string", + "nullable": true + }, + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "MessageDtoPaginationContainer": { + "type": "object", + "properties": { + "skip": { + "type": "integer", + "format": "int32" + }, + "take": { + "type": "integer", + "format": "int32" + }, + "count": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MessageDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "TelemetryInfoDto": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "timeZoneId": { + "type": "string", + "nullable": true + }, + "timeZoneOffsetTotalHours": { + "type": "number", + "format": "double" + }, + "caption": { + "type": "string", + "nullable": true + }, + "cluster": { + "type": "string", + "nullable": true + }, + "deposit": { + "type": "string", + "nullable": true + }, + "hmiVersion": { + "type": "string", + "nullable": true + }, + "plcVersion": { + "type": "string", + "nullable": true + }, + "comment": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "TelemetryMessageDto": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "idEvent": { + "type": "integer", + "format": "int32" + }, + "state": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "idTelemetryUser": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "arg0": { + "type": "string", + "nullable": true + }, + "arg1": { + "type": "string", + "nullable": true + }, + "arg2": { + "type": "string", + "nullable": true + }, + "arg3": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "TelemetryUserDto": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "surname": { + "type": "string", + "nullable": true + }, + "patronymic": { + "type": "string", + "nullable": true + }, + "level": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "UserTokenDto": { + "type": "object", + "properties": { + "login": { + "type": "string", + "nullable": true + }, + "level": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "surname": { + "type": "string", + "nullable": true + }, + "patronymic": { + "type": "string", + "nullable": true + }, + "id": { + "type": "integer", + "format": "int32" + }, + "customerName": { + "type": "string", + "nullable": true + }, + "roleName": { + "type": "string", + "nullable": true + }, + "token": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "WellDto": { + "type": "object", + "properties": { + "caption": { + "type": "string", + "nullable": true + }, + "cluster": { + "type": "string", + "nullable": true + }, + "deposit": { + "type": "string", + "nullable": true + }, + "id": { + "type": "integer", + "format": "int32" + }, + "lastData": { + "nullable": true + } + }, + "additionalProperties": false + } + }, + "securitySchemes": { + "Bearer": { + "type": "apiKey", + "description": "JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'", + "name": "Authorization", + "in": "header" + } + } + }, + "security": [ + { + "Bearer": [ ] + } + ] +} \ No newline at end of file