forked from ddrilling/AsbCloudServer
autocleanup
This commit is contained in:
parent
6de9e7116e
commit
fce20a2a10
@ -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
|
||||
|
@ -8,8 +8,4 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AsbCloudDb\AsbCloudDb.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Сообщение получаемое по телеметрии и отправляемое в frontend
|
||||
/// </summary>
|
||||
public class DataSaubBaseDto
|
||||
{
|
||||
//[JsonPropertyName("date")]
|
||||
@ -20,6 +22,11 @@ namespace AsbCloudApp.Data
|
||||
/// </summary>
|
||||
public int? Mode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// telemetry user
|
||||
/// </summary>
|
||||
public string User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя
|
||||
/// </summary>
|
||||
@ -31,9 +38,19 @@ namespace AsbCloudApp.Data
|
||||
public double? BitDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Высота
|
||||
/// Талевый блок. Положение
|
||||
/// </summary>
|
||||
public double? BlockHeight { get; set; }
|
||||
public double? BlockPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Мин положение
|
||||
/// </summary>
|
||||
public double? BlockPositionMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Макс положение
|
||||
/// </summary>
|
||||
public double? BlockPositionMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Скорость
|
||||
@ -45,6 +62,21 @@ namespace AsbCloudApp.Data
|
||||
/// </summary>
|
||||
public double? BlockSpeedSp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Задание скорости для роторного бурения
|
||||
/// </summary>
|
||||
public double? BlockSpeedSpRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Задание скорости для режима слайда
|
||||
/// </summary>
|
||||
public double? BlockSpeedSpSlide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Талевый блок. Задание скорости для проработки
|
||||
/// </summary>
|
||||
public double? BlockSpeedSpDevelop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Давтение
|
||||
/// </summary>
|
||||
@ -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; }
|
||||
|
12
AsbCloudApp/Data/EventDto.cs
Normal file
12
AsbCloudApp/Data/EventDto.cs
Normal file
@ -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; }
|
||||
}
|
||||
}
|
20
AsbCloudApp/Data/MessageDto.cs
Normal file
20
AsbCloudApp/Data/MessageDto.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Сообщение для frontend
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
}
|
43
AsbCloudApp/Data/PaginationContainer.cs
Normal file
43
AsbCloudApp/Data/PaginationContainer.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Контейнер для поддержки постраничного просмотра таблиц
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class PaginationContainer<T>
|
||||
{
|
||||
public PaginationContainer()
|
||||
{
|
||||
Items = new List<T>(4);
|
||||
}
|
||||
|
||||
public PaginationContainer(int capacity)
|
||||
{
|
||||
Items = new List<T>(capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Кол-во записей пропущеных с начала таблицы в запросе от api
|
||||
/// </summary>
|
||||
public int Skip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Кол-во записей в запросе от api
|
||||
/// </summary>
|
||||
public int Take { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Кол-во записей всего в таблице
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Данные
|
||||
/// </summary>
|
||||
public List<T> Items { get; set; }
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Формат посылки от панели к облаку.
|
||||
/// Панель копит у себя данные и при удачной отправке помечает как отправленные.
|
||||
/// </summary>
|
||||
public class TelemetryDataDto
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Версия ПО панели.
|
||||
/// Нужна будет для разбора информации
|
||||
/// </summary>
|
||||
public string HmiVersion { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public List<DataSaubBaseDto> DataSaub { get; set; }
|
||||
|
||||
/// TODO:
|
||||
//public List<EventDto> EventsDictiotary { get; set; }
|
||||
|
||||
//public List<MessageDto> Messages { get; set; }
|
||||
}
|
||||
}
|
9
AsbCloudApp/Data/TelemetryDto.cs
Normal file
9
AsbCloudApp/Data/TelemetryDto.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class TelemetryDto<T>
|
||||
{
|
||||
public string HmiVersion { get; set; }
|
||||
|
||||
public T Payload { get; set; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
25
AsbCloudApp/Data/TelemetryMessageDto.cs
Normal file
25
AsbCloudApp/Data/TelemetryMessageDto.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Сообщение получаемое от телеметрии
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
}
|
15
AsbCloudApp/Data/TelemetryUserDto.cs
Normal file
15
AsbCloudApp/Data/TelemetryUserDto.cs
Normal file
@ -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; }
|
||||
}
|
||||
}
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class UserBaseDto
|
||||
{
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class UserTokenDto : UserBaseDto
|
||||
{
|
||||
|
@ -4,8 +4,10 @@ using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface ITelemetryDataService
|
||||
public interface IDataService
|
||||
{
|
||||
IEnumerable<DataSaubBaseDto> Get(int wellId, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024);
|
||||
|
||||
void UpdateData(string uid, IEnumerable<DataSaubBaseDto> dtos);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IDepositService
|
||||
{
|
||||
}
|
||||
}
|
10
AsbCloudApp/Services/IEventService.cs
Normal file
10
AsbCloudApp/Services/IEventService.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IEventService
|
||||
{
|
||||
void Upsert(string uid, IEnumerable<EventDto> dtos);
|
||||
}
|
||||
}
|
12
AsbCloudApp/Services/IMessageService.cs
Normal file
12
AsbCloudApp/Services/IMessageService.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IMessageService
|
||||
{
|
||||
PaginationContainer<MessageDto> GetMessages(int wellId, IEnumerable<int> categoryids = null, DateTime begin = default, DateTime end = default, int skip = 0, int take = 32);
|
||||
void Insert(string uid, IEnumerable<TelemetryMessageDto> dtos);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
10
AsbCloudApp/Services/ITelemetryUserService.cs
Normal file
10
AsbCloudApp/Services/ITelemetryUserService.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface ITelemetryUserService
|
||||
{
|
||||
void Upsert(string uid, IEnumerable<TelemetryUserDto> dtos);
|
||||
}
|
||||
}
|
@ -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<Cluster> Clusters { get; set; }
|
||||
public virtual DbSet<Customer> Customers { get; set; }
|
||||
public virtual DbSet<DataSaubBase> 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<TelemetryUser>(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<Event>(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<UserRole>(entity =>
|
||||
{
|
||||
entity.HasData(new List<UserRole>{
|
||||
new UserRole{ Id = 1, Caption = "Администратор", },
|
||||
}); ;
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Customer>(entity =>
|
||||
{
|
||||
entity.HasData(new List<Customer>{
|
||||
new Customer{ Id = 1, Caption = "\"ООО\" АСБ", },
|
||||
}); ;
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity<User>(entity =>
|
||||
@ -148,14 +158,14 @@ namespace AsbCloudDb.Model
|
||||
modelBuilder.Entity<Deposit>(entity =>
|
||||
{
|
||||
entity.HasData(new List<Deposit> {
|
||||
new Deposit{Id = 1, Caption = "месторождение" },
|
||||
new Deposit{Id = 1, Caption = "м/р 1" },
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Cluster>(entity =>
|
||||
{
|
||||
entity.HasData(new List<Cluster> {
|
||||
new Cluster{Id = 1, Caption = "месторождение", IdDeposit = 1 },
|
||||
new Cluster{Id = 1, Caption = "куст 1", IdDeposit = 1 },
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -24,6 +24,7 @@ namespace AsbCloudDb.Model
|
||||
|
||||
[InverseProperty(nameof(User.Customer))]
|
||||
public virtual ICollection<User> Users { get; set; }
|
||||
|
||||
[InverseProperty(nameof(Well.Customer))]
|
||||
public virtual ICollection<Well> Wells { get; set; }
|
||||
}
|
||||
|
@ -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("Осевая нагрузка")]
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
public interface IId
|
||||
{
|
||||
|
@ -13,28 +13,37 @@ namespace AsbCloudDb.Model
|
||||
[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))]
|
||||
|
@ -10,7 +10,6 @@ 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 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<Message> Messages { get; set; }
|
||||
|
||||
[InverseProperty(nameof(TelemetryUser.Telemetry))]
|
||||
public virtual ICollection<TelemetryUser> Users { get; set; }
|
||||
|
||||
[InverseProperty(nameof(Event.Telemetry))]
|
||||
public virtual ICollection<Event> Events { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
19
AsbCloudDb/Model/TelemetryInfo.cs
Normal file
19
AsbCloudDb/Model/TelemetryInfo.cs
Normal file
@ -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; }
|
||||
}
|
||||
}
|
@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,10 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IAuthService, AuthService>();
|
||||
services.AddTransient<IWellService, WellService>();
|
||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
||||
services.AddTransient<ITelemetryDataService, TelemetryDataService>();
|
||||
services.AddTransient<IDataService, DataService>();
|
||||
services.AddTransient<IMessageService, MessageService>();
|
||||
services.AddTransient<IEventService, EventService>();
|
||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
@ -34,6 +37,12 @@ namespace AsbCloudInfrastructure
|
||||
{
|
||||
cfg.CreateMap<DataSaubBase, DataSaubBaseDto>();
|
||||
cfg.CreateMap<DataSaubBaseDto, DataSaubBase>();
|
||||
|
||||
cfg.CreateMap<Message, TelemetryMessageDto>();
|
||||
cfg.CreateMap<TelemetryMessageDto, Message>();
|
||||
|
||||
cfg.CreateMap<TelemetryInfo, TelemetryInfoDto>();
|
||||
cfg.CreateMap<TelemetryInfoDto, TelemetryInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<string, IEnumerable<object>> cache = new ConcurrentDictionary<string, IEnumerable<object>>();
|
||||
private readonly ConcurrentDictionary<string, IEnumerable<object>> cache = new ConcurrentDictionary<string, IEnumerable<object>>();
|
||||
|
||||
public ICacheTable<TEntity> GetCachedTable<TEntity>(DbContext context)
|
||||
where TEntity : class
|
||||
|
@ -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<TEntity> : ICacheTable<TEntity> where TEntity : class
|
||||
{
|
||||
private readonly DbContext context;
|
||||
private List<TEntity> entities;
|
||||
private readonly List<TEntity> cached;
|
||||
|
||||
internal CacheTable(DbContext context, List<TEntity> 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<TEntity>().ToList();
|
||||
entities.AddRange(dbEntities);
|
||||
return entities.Count();
|
||||
cached.AddRange(dbEntities);
|
||||
return cached.Count();
|
||||
}
|
||||
|
||||
public async Task<int> RefreshAsync(CancellationToken token = default)
|
||||
{
|
||||
entities.Clear();
|
||||
cached.Clear();
|
||||
var dbEntities = await context.Set<TEntity>().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<TEntity>();
|
||||
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity> 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<TEntity> UpsertAsync(TEntity entity, CancellationToken token = default)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity> 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<TEntity> Upsert(IEnumerable<TEntity> entities)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
|
||||
var upsertedEntries = new List<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity>>(entities.Count());
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity> 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<IEnumerable<TEntity>> UpsertAsync(IEnumerable<TEntity> entities, CancellationToken token = default)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
|
||||
var upsertedEntries = new List<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity>>(entities.Count());
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<TEntity> 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<TEntity, bool> predicate)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
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<TEntity, bool> predicate, CancellationToken token = default)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
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<TEntity>();
|
||||
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<TEntity>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
void Remove(Func<TEntity, bool> predicate);
|
||||
IEnumerable<TEntity> Select(Func<TEntity, bool> predicate, RefreshMode refreshMode = RefreshMode.IfResultEmpty);
|
||||
IEnumerable<TEntity> Update(Func<TEntity, bool> predicate, Action<TEntity> mutation);
|
||||
TEntity Upsert(TEntity entity);
|
||||
IEnumerable<TEntity> Upsert(IEnumerable<TEntity> entities);
|
||||
|
||||
//----- ASYNC ------
|
||||
|
||||
@ -33,5 +35,7 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
Task<IEnumerable<TEntity>> SelectAsync(Func<TEntity, bool> predicate, CancellationToken token = default);
|
||||
Task<IEnumerable<TEntity>> SelectAsync(Func<TEntity, bool> predicate, RefreshMode refreshMode = RefreshMode.IfResultEmpty, CancellationToken token = default);
|
||||
Task<IEnumerable<TEntity>> UpdateAsync(Func<TEntity, bool> predicate, Action<TEntity> mutation, CancellationToken token = default);
|
||||
Task<TEntity> UpsertAsync(TEntity entity, CancellationToken token = default);
|
||||
Task<IEnumerable<TEntity>> UpsertAsync(IEnumerable<TEntity> entities, CancellationToken token = default);
|
||||
}
|
||||
}
|
@ -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<Telemetry> cacheTelemetry;
|
||||
private ICacheTable<Well> cacheWells;
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly IMapper mapper;
|
||||
private readonly ICacheTable<Telemetry> cacheTelemetry;
|
||||
private readonly ICacheTable<Well> 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<Telemetry>((AsbCloudDbContext)db);
|
||||
cacheWells = cacheDb.GetCachedTable<Well>((AsbCloudDbContext)db);
|
||||
@ -64,5 +65,23 @@ namespace AsbCloudInfrastructure.Services
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void UpdateData(string uid, IEnumerable<DataSaubBaseDto> dtos)
|
||||
{
|
||||
var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid);
|
||||
|
||||
if ((dtos != default) && (dtos.Count() > 0))
|
||||
{
|
||||
foreach (var item in dtos)
|
||||
{
|
||||
var dataSaub = mapper.Map<DataSaubBase>(item);
|
||||
dataSaub.IdTelemetry = telemetryId;
|
||||
db.DataSaubBases.Add(dataSaub);
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
56
AsbCloudInfrastructure/Services/EventService.cs
Normal file
56
AsbCloudInfrastructure/Services/EventService.cs
Normal file
@ -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<Event> cacheEvents;
|
||||
|
||||
public EventService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
|
||||
{
|
||||
this.db = db;
|
||||
this.telemetryService = telemetryService;
|
||||
cacheEvents = cacheDb.GetCachedTable<Event>((AsbCloudDbContext)db);
|
||||
}
|
||||
|
||||
public void Upsert(string uid, IEnumerable<EventDto> 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();
|
||||
}
|
||||
}
|
||||
}
|
127
AsbCloudInfrastructure/Services/MessageService.cs
Normal file
127
AsbCloudInfrastructure/Services/MessageService.cs
Normal file
@ -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<Event> cacheEvents;
|
||||
private readonly ICacheTable<TelemetryUser> cacheTUsers;
|
||||
private readonly ICacheTable<Telemetry> cacheTelemetry;
|
||||
private readonly ICacheTable<Well> cacheWells;
|
||||
|
||||
public MessageService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService, MapperConfiguration mapperConfiguration)
|
||||
{
|
||||
this.db = db;
|
||||
this.telemetryService = telemetryService;
|
||||
mapper = mapperConfiguration.CreateMapper();
|
||||
cacheEvents = cacheDb.GetCachedTable<Event>((AsbCloudDbContext)db);
|
||||
cacheTUsers = cacheDb.GetCachedTable<TelemetryUser>((AsbCloudDbContext)db);
|
||||
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
|
||||
cacheWells = cacheDb.GetCachedTable<Well>((AsbCloudDbContext)db);
|
||||
}
|
||||
|
||||
public PaginationContainer<MessageDto> GetMessages(int wellId, IEnumerable<int> 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<MessageDto>() { 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<TelemetryMessageDto> dtos)
|
||||
{
|
||||
if (dtos.Count() == 0)
|
||||
return;
|
||||
|
||||
var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var entity = mapper.Map<Message>(dto);
|
||||
entity.IdTelemetry = telemetryId;
|
||||
db.Messages.Add(entity);
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Telemetry> cacheTelemetry;
|
||||
private readonly ICacheTable<Well> cacheWell;
|
||||
|
||||
public TelemetryService(IAsbCloudDbContext db, CacheDb cacheDb, MapperConfiguration mapperConfiguration)
|
||||
{
|
||||
this.db = db;
|
||||
mapper = mapperConfiguration.CreateMapper();
|
||||
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
|
||||
cacheWell = cacheDb.GetCachedTable<Well>((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<TelemetryInfo>(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, });
|
||||
|
||||
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<DataSaubBase>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
58
AsbCloudInfrastructure/Services/TelemetryUserService.cs
Normal file
58
AsbCloudInfrastructure/Services/TelemetryUserService.cs
Normal file
@ -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<TelemetryUser> cacheTUsers;
|
||||
|
||||
public TelemetryUserService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
|
||||
{
|
||||
this.db = db;
|
||||
this.telemetryService = telemetryService;
|
||||
cacheTUsers = cacheDb.GetCachedTable<TelemetryUser>((AsbCloudDbContext)db);
|
||||
}
|
||||
|
||||
public void Upsert(string uid, IEnumerable<TelemetryUserDto> 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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<WellDto> 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<DataSaubBaseDto>(well.Telemetry.LastDataSaub);
|
||||
|
||||
return wellDto;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
45
AsbCloudWebApi/Controllers/MessageController.cs
Normal file
45
AsbCloudWebApi/Controllers/MessageController.cs
Normal file
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выдает список сообщений по скважине
|
||||
/// </summary>
|
||||
/// <param name="wellId">id скважины</param>
|
||||
/// <param name="categoryids">список категорий</param>
|
||||
/// <param name="begin">дата начала</param>
|
||||
/// <param name="end">окончание</param>
|
||||
/// <param name="skip">для пагинации кол-во записей пропустить</param>
|
||||
/// <param name="take">для пагинации кол-во записей </param>
|
||||
/// <returns>список сообщений по скважине</returns>
|
||||
[HttpGet]
|
||||
[Route("{wellId}/message")]
|
||||
[ProducesResponseType(typeof(PaginationContainer<MessageDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public IActionResult Get(int wellId, [FromQuery] IEnumerable<int> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<TelemetryHub> telemetryHubContext;
|
||||
|
||||
public TelemetryController(ITelemetryService telemetryService, IHubContext<TelemetryHub> telemetryHubContext)
|
||||
public TelemetryController(
|
||||
ITelemetryService telemetryService,
|
||||
IDataService DataService,
|
||||
IMessageService messageService,
|
||||
IEventService eventService,
|
||||
ITelemetryUserService telemetryUserService,
|
||||
IHubContext<TelemetryHub> 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
|
||||
/// Принимает данные от разных систем по скважине
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный идентификатор отправителя</param>
|
||||
/// <param name="data">Данные</param>
|
||||
/// <param name="dtos">Данные</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("{uid}/data")]
|
||||
public IActionResult Data(string uid, [FromBody] TelemetryDataDto data)
|
||||
public IActionResult Data(string uid, [FromBody] IEnumerable<DataSaubBaseDto> dtos)
|
||||
{
|
||||
telemetryService.UpdateData(uid, data);
|
||||
var wellId = telemetryService.GetWellIdByTelemetryUid(uid);
|
||||
DataService.UpdateData(uid, dtos);
|
||||
|
||||
var wellId = telemetryService.GetWellIdByUid(uid);
|
||||
|
||||
if (wellId != null && data.DataSaub?.Count > 0)
|
||||
Task.Run(() => telemetryHubContext.Clients.Group($"well_{wellId}").SendAsync(nameof(ITelemetryHubClient.ReceiveDataSaub), data.DataSaub) );
|
||||
if (wellId != null && dtos.Any())
|
||||
Task.Run(() => telemetryHubContext.Clients.Group($"well_{wellId}").SendAsync(nameof(ITelemetryHubClient.ReceiveDataSaub), dtos));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Принимает список новых сообщений от телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный идентификатор отправителя</param>
|
||||
/// <param name="dtos">сообщения</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("{uid}/message")]
|
||||
public IActionResult Message(string uid, [FromBody] IEnumerable<TelemetryMessageDto> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Принимает справочник событий
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный идентификатор отправителя</param>
|
||||
/// <param name="events">справочник событий</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("{uid}/event")]
|
||||
public IActionResult Events(string uid, [FromBody] List<EventDto> events)
|
||||
{
|
||||
eventService.Upsert(uid, events);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Принимает справочник пользователей телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный идентификатор отправителя</param>
|
||||
/// <param name="users">справочник пользователей телеметрии</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("{uid}/user")]
|
||||
public IActionResult Users(string uid, [FromBody] List<TelemetryUserDto> users)
|
||||
{
|
||||
telemetryUserService.Upsert(uid, users);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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'",
|
||||
|
@ -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<DataSaubBaseDto> data);
|
||||
Task ReceiveDataSaub(IEnumerable<DataSaubBaseDto> dtos);
|
||||
|
||||
Task ReceiveMessages(IEnumerable<MessageDto> dtos);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
- синхронизация архива телеметрии
|
||||
|
||||
|
||||
|
||||
- мониторинг активно передающих скважин
|
||||
- доделать секционирование.
|
||||
- редуцирование архива телеметрии по принципу второй производной. Если вторая производная ~0, то промежуточные значения можно удалить.
|
||||
- редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функиями, сохранять экстремумы и ближайшие к ним значения.
|
||||
|
@ -5,6 +5,6 @@
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
RAMAMBA!
|
||||
|
||||
</body>
|
||||
</html>
|
6
AsbCloudWebApi/кейсы для админки.txt
Normal file
6
AsbCloudWebApi/кейсы для админки.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Моменты в БД за которыми надо приглядывать.
|
||||
|
||||
Есть t_message для которой нет t_event | Ошибка синхронизации
|
||||
Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого
|
||||
2 t_telemetry с не уникальными uid
|
||||
Провалы в непрерывной t_data.
|
@ -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<AsbCloudDbContext>()
|
||||
// .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
|
||||
// .Options;
|
||||
//var context = new AsbCloudDbContext(options);
|
||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
||||
.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
|
||||
//{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -113,7 +111,7 @@ namespace SaubPanelOnlineSender
|
||||
AxialLoadLimitMax = rnd.NextDouble() * 100d,
|
||||
AxialLoadSp = rnd.NextDouble() * 100d,
|
||||
BitDepth = rnd.NextDouble() * 100d,
|
||||
BlockHeight = rnd.NextDouble()*100d,
|
||||
BlockPosition = rnd.NextDouble() * 100d,
|
||||
BlockSpeed = rnd.NextDouble() * 100d,
|
||||
WellDepth = rnd.NextDouble() * 100d,
|
||||
BlockSpeedSp = rnd.NextDouble() * 100d,
|
||||
|
112
SyncDicts/Program.cs
Normal file
112
SyncDicts/Program.cs
Normal file
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Описывает процесс синхронизации словарей БД
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
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<T>(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;
|
||||
}
|
||||
}
|
||||
}
|
23
SyncDicts/SyncDicts.csproj
Normal file
23
SyncDicts/SyncDicts.csproj
Normal file
@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AsbCloudApp\AsbCloudApp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="AsbSaubDbModel">
|
||||
<HintPath>..\..\..\SAUB\asbsaub3\AsbSaubDbModel\bin\Release\netcoreapp3.1\AsbSaubDbModel.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
1022
swagger.json
Normal file
1022
swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user