mirror of
https://gitee.com/iioter/iotgateway.git
synced 2024-11-29 18:28:09 +08:00
增加属性上传、整合日志
This commit is contained in:
parent
bb28946f19
commit
27c0433458
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
801
IoTGateway.DataAccess/Migrations/20220323063908_attribut.Designer.cs
generated
Normal file
801
IoTGateway.DataAccess/Migrations/20220323063908_attribut.Designer.cs
generated
Normal file
@ -0,0 +1,801 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using IoTGateway.DataAccess;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IoTGateway.DataAccess.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20220323063908_attribut")]
|
||||
partial class attribut
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.1");
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.Device", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("AutoStart")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DeviceTypeEnum")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("DriverId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("Index")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("ParentId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("DriverId");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("Devices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.DeviceConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DataSide")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceConfigName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("DeviceId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("EnumInfo")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("DeviceId");
|
||||
|
||||
b.ToTable("DeviceConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.DeviceVariable", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DataType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceAddress")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("DeviceId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Expressions")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Method")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ProtectType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("DeviceId");
|
||||
|
||||
b.ToTable("DeviceVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.Driver", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AssembleName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AuthorizesNum")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DriverName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("Drivers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.SystemConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GatewayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("IoTPlatformType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MqttIp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("MqttPort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MqttUName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MqttUPwd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("SystemConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.ActionLog", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ActionName")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("ActionTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ActionUrl")
|
||||
.HasMaxLength(250)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Duration")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("IP")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ITCode")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("LogType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ModuleName")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Remark")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("ActionLogs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.DataPrivilege", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Domain")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GroupCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RelateId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TableName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("DataPrivileges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FileAttachment", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ExtraInfo")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<byte[]>("FileData")
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.Property<string>("FileExt")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("HandlerInfo")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("Length")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SaveMode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UploadTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("FileAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GroupCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GroupName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GroupRemark")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TenantCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("FrameworkGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkMenu", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ActionName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClassName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("DisplayOrder")
|
||||
.IsRequired()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Domain")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("FolderOnly")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Icon")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsInherit")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool?>("IsInside")
|
||||
.IsRequired()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsPublic")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MethodName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ModuleName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PageName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("ParentId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("ShowOnMenu")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("FrameworkMenus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkRole", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleRemark")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TenantCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("FrameworkRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkUser", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CellPhone")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("Gender")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("HomePhone")
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ITCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsValid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("PhotoId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TenantCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ZipCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("PhotoId");
|
||||
|
||||
b.ToTable("FrameworkUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkUserGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GroupCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("FrameworkUserGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkUserRole", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("FrameworkUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FunctionPrivilege", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool?>("Allowed")
|
||||
.IsRequired()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("MenuItemId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UpdateBy")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("MenuItemId");
|
||||
|
||||
b.ToTable("FunctionPrivileges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.PersistedGrant", b =>
|
||||
{
|
||||
b.Property<Guid>("ID")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreationTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Expiration")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RefreshToken")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("PersistedGrants");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.Device", b =>
|
||||
{
|
||||
b.HasOne("IoTGateway.Model.Driver", "Driver")
|
||||
.WithMany()
|
||||
.HasForeignKey("DriverId");
|
||||
|
||||
b.HasOne("IoTGateway.Model.Device", "Parent")
|
||||
.WithMany("Children")
|
||||
.HasForeignKey("ParentId");
|
||||
|
||||
b.Navigation("Driver");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.DeviceConfig", b =>
|
||||
{
|
||||
b.HasOne("IoTGateway.Model.Device", "Device")
|
||||
.WithMany("DeviceConfigs")
|
||||
.HasForeignKey("DeviceId");
|
||||
|
||||
b.Navigation("Device");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.DeviceVariable", b =>
|
||||
{
|
||||
b.HasOne("IoTGateway.Model.Device", "Device")
|
||||
.WithMany("DeviceVariables")
|
||||
.HasForeignKey("DeviceId");
|
||||
|
||||
b.Navigation("Device");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkMenu", b =>
|
||||
{
|
||||
b.HasOne("WalkingTec.Mvvm.Core.FrameworkMenu", "Parent")
|
||||
.WithMany("Children")
|
||||
.HasForeignKey("ParentId");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkUser", b =>
|
||||
{
|
||||
b.HasOne("WalkingTec.Mvvm.Core.FileAttachment", "Photo")
|
||||
.WithMany()
|
||||
.HasForeignKey("PhotoId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("Photo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FunctionPrivilege", b =>
|
||||
{
|
||||
b.HasOne("WalkingTec.Mvvm.Core.FrameworkMenu", "MenuItem")
|
||||
.WithMany("Privileges")
|
||||
.HasForeignKey("MenuItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("MenuItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IoTGateway.Model.Device", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
|
||||
b.Navigation("DeviceConfigs");
|
||||
|
||||
b.Navigation("DeviceVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WalkingTec.Mvvm.Core.FrameworkMenu", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
|
||||
b.Navigation("Privileges");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
26
IoTGateway.DataAccess/Migrations/20220323063908_attribut.cs
Normal file
26
IoTGateway.DataAccess/Migrations/20220323063908_attribut.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IoTGateway.DataAccess.Migrations
|
||||
{
|
||||
public partial class attribut : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "DataSide",
|
||||
table: "DeviceConfigs",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DataSide",
|
||||
table: "DeviceConfigs");
|
||||
}
|
||||
}
|
||||
}
|
@ -78,6 +78,9 @@ namespace IoTGateway.DataAccess.Migrations
|
||||
b.Property<DateTime?>("CreateTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DataSide")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -17,4 +17,11 @@ namespace IoTGateway.Model
|
||||
[Display(Name = "读写")]
|
||||
ReadAndWrite = 1
|
||||
}
|
||||
|
||||
public enum DataSide
|
||||
{
|
||||
AnySide=0,
|
||||
//ServerSide=1,
|
||||
ClientSide=2,
|
||||
}
|
||||
}
|
@ -8,6 +8,8 @@ namespace IoTGateway.Model
|
||||
{
|
||||
[Display(Name = "名称")]
|
||||
public string DeviceConfigName { get; set; }
|
||||
[Display(Name = "属性侧")]
|
||||
public DataSide DataSide { get; set; }
|
||||
[Display(Name = "描述")]
|
||||
public string Description { get; set; }
|
||||
[Display(Name = "值")]
|
||||
|
@ -51,6 +51,7 @@ namespace IoTGateway.ViewModel.BasicData.DeviceConfigVMs
|
||||
{
|
||||
return new List<GridColumn<DeviceConfig_View>>{
|
||||
this.MakeGridHeader(x => x.DeviceConfigName).SetWidth(100),
|
||||
this.MakeGridHeader(x => x.DataSide).SetWidth(100),
|
||||
this.MakeGridHeader(x => x.Description).SetWidth(100),
|
||||
this.MakeGridHeader(x => x.Value).SetWidth(100),
|
||||
this.MakeGridHeader(x => x.DeviceName_view).SetWidth(100),
|
||||
@ -62,25 +63,28 @@ namespace IoTGateway.ViewModel.BasicData.DeviceConfigVMs
|
||||
public override IOrderedQueryable<DeviceConfig_View> GetSearchQuery()
|
||||
{
|
||||
var query = DC.Set<DeviceConfig>()
|
||||
.CheckContain(Searcher.DeviceConfigName, x=>x.DeviceConfigName)
|
||||
.CheckContain(Searcher.Value, x=>x.Value)
|
||||
.CheckEqual(Searcher.DeviceId, x=>x.DeviceId)
|
||||
.CheckContain(Searcher.DeviceConfigName, x => x.DeviceConfigName)
|
||||
.CheckContain(Searcher.Value, x => x.Value)
|
||||
.CheckEqual(Searcher.DeviceId, x => x.DeviceId)
|
||||
.CheckEqual(Searcher.DataSide, x => x.DataSide)
|
||||
.Select(x => new DeviceConfig_View
|
||||
{
|
||||
ID = x.ID,
|
||||
ID = x.ID,
|
||||
DeviceConfigName = x.DeviceConfigName,
|
||||
DataSide = x.DataSide,
|
||||
Description = x.Description,
|
||||
Value = x.Value,
|
||||
EnumInfo = x.EnumInfo,
|
||||
DeviceName_view = x.Device.DeviceName,
|
||||
})
|
||||
.OrderBy(x => x.DeviceName_view).ThenBy(x=>x.DeviceConfigName);
|
||||
.OrderBy(x => x.DeviceName_view).ThenBy(x => x.DeviceConfigName);
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class DeviceConfig_View : DeviceConfig{
|
||||
public class DeviceConfig_View : DeviceConfig
|
||||
{
|
||||
[Display(Name = "设备名")]
|
||||
public String DeviceName_view { get; set; }
|
||||
|
||||
|
@ -14,6 +14,8 @@ namespace IoTGateway.ViewModel.BasicData.DeviceConfigVMs
|
||||
{
|
||||
[Display(Name = "名称")]
|
||||
public String DeviceConfigName { get; set; }
|
||||
[Display(Name = "属性侧")]
|
||||
public DataSide? DataSide { get; set; }
|
||||
[Display(Name = "值")]
|
||||
public String Value { get; set; }
|
||||
public List<ComboSelectListItem> AllDevices { get; set; }
|
||||
|
56
IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs
Normal file
56
IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Plugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WalkingTec.Mvvm.Core;
|
||||
using WalkingTec.Mvvm.Core.Extensions;
|
||||
using IoTGateway.Model;
|
||||
|
||||
namespace IoTGateway.ViewModel.BasicData.DeviceVMs
|
||||
{
|
||||
public class AttributeVM : BaseVM
|
||||
{
|
||||
public string 请求结果 { get; set; }
|
||||
public string 设备名称 { get; set; }
|
||||
|
||||
public void Request()
|
||||
{
|
||||
using (var transaction = DC.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
var device = DC.Set<Device>().Where(x => x.ID == Guid.Parse(FC["id"].ToString())).Include(x => x.Parent).Include(x=>x.DeviceConfigs).Include(x => x.Driver).FirstOrDefault();
|
||||
|
||||
if (device == null)
|
||||
请求结果 = "复制失败,找不到设备";
|
||||
else
|
||||
{
|
||||
var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient;
|
||||
myMqttClient.RequestAttributes(device.DeviceName, true, device.DeviceConfigs.Where(x => x.DataSide == DataSide.AnySide).Select(x => x.DeviceConfigName).ToArray());
|
||||
}
|
||||
DC.SaveChanges();
|
||||
transaction.Commit();
|
||||
请求结果 = "请求成功";
|
||||
|
||||
var pluginManager = Wtm.ServiceProvider.GetService(typeof(DeviceService)) as DeviceService;
|
||||
pluginManager?.UpdateDevice(device);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transaction.Rollback();
|
||||
|
||||
请求结果 = $"请求超时,{ex}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void InitVM()
|
||||
{
|
||||
var device = DC.Set<Device>().AsNoTracking().Include(x => x.Parent).Where(x => x.ID == Guid.Parse(FC["id"].ToString())).FirstOrDefault();
|
||||
设备名称 = $"{device?.Parent?.DeviceName}===>{device?.DeviceName}";
|
||||
|
||||
base.InitVM();
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVMs
|
||||
return new List<GridAction>
|
||||
{
|
||||
this.MakeAction("Device","Copy","设备复制","设备复制", GridActionParameterTypesEnum.SingleId,"BasicData",600).SetIconCls("layui-icon layui-icon-template-1").SetPromptMessage("你确定复制设备,包括配置参数和变量?").SetDialogTitle("复制设备确认").SetHideOnToolBar(true).SetShowInRow(true).SetBindVisiableColName("copy"),
|
||||
this.MakeAction("Device","Attribute","请求属性","请求属性", GridActionParameterTypesEnum.SingleId,"BasicData",600).SetIconCls("layui-icon layui-icon-download-circle").SetPromptMessage("你确定请求客户端属性和共享属性吗?").SetDialogTitle("请求属性确认").SetHideOnToolBar(true).SetShowInRow(true).SetBindVisiableColName("attribute"),
|
||||
this.MakeAction("Device","CreateGroup","创建组","创建组", GridActionParameterTypesEnum.NoId,"BasicData",600).SetIconCls("_wtmicon _wtmicon-zuzhiqunzu").SetDialogTitle("创建组").SetShowInRow(false),
|
||||
this.MakeStandardAction("Device", GridActionStandardTypesEnum.Create, "创建设备","BasicData", dialogWidth: 800,name:"创建设备").SetIconCls("layui-icon layui-icon-senior"),
|
||||
this.MakeStandardAction("Device", GridActionStandardTypesEnum.Edit, Localizer["Sys.Edit"], "BasicData", dialogWidth: 800),
|
||||
@ -45,6 +46,10 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVMs
|
||||
if(a.DeviceTypeEnum== DeviceTypeEnum.Device)
|
||||
return "true";
|
||||
return "false";
|
||||
}),this.MakeGridHeader(x=>"attribute").SetHide().SetFormat((a,b)=>{
|
||||
if(a.DeviceTypeEnum== DeviceTypeEnum.Device)
|
||||
return "true";
|
||||
return "false";
|
||||
}),
|
||||
this.MakeGridHeaderAction(width: 280)
|
||||
};
|
||||
|
@ -44,10 +44,10 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVariableVMs
|
||||
{
|
||||
foreach (var item in device.Children)
|
||||
{
|
||||
var deviceThread = deviceService.DeviceThreads.Where(x => x.Device.ID.ToString() == (string)item.Value).FirstOrDefault();
|
||||
var deviceThread = deviceService.DeviceThreads.Where(x => x._device.ID.ToString() == (string)item.Value).FirstOrDefault();
|
||||
|
||||
item.Text = item.Text;
|
||||
item.Icon = deviceThread.Device.AutoStart ? (deviceThread.Driver.IsConnected ? "layui-icon-link" : "layui-icon-unlink") : "layui-icon-pause";
|
||||
item.Icon = deviceThread._device.AutoStart ? (deviceThread._driver.IsConnected ? "layui-icon-link" : "layui-icon-unlink") : "layui-icon-pause";
|
||||
item.Expended = true;
|
||||
}
|
||||
}
|
||||
@ -86,7 +86,7 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVariableVMs
|
||||
var deviceService = Wtm.ServiceProvider.GetService(typeof(DeviceService)) as DeviceService;
|
||||
foreach (var item in EntityList)
|
||||
{
|
||||
var DapThread = deviceService.DeviceThreads.Where(x => x.Device.ID == item.DeviceId).FirstOrDefault();
|
||||
var DapThread = deviceService.DeviceThreads.Where(x => x._device.ID == item.DeviceId).FirstOrDefault();
|
||||
if (DapThread?.DeviceValues != null && DapThread.DeviceValues.ContainsKey(item.ID))
|
||||
{
|
||||
item.Value = DapThread.DeviceValues[item.ID].Value?.ToString();
|
||||
|
@ -32,7 +32,7 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVariableVMs
|
||||
{
|
||||
var deviceService = Wtm.ServiceProvider.GetService(typeof(DeviceService)) as DeviceService;
|
||||
AllMethods = deviceService.GetDriverMethods(Entity.DeviceId);
|
||||
var DapThread = deviceService.DeviceThreads.Where(x => x.Device.ID == Entity.DeviceId).FirstOrDefault();
|
||||
var DapThread = deviceService.DeviceThreads.Where(x => x._device.ID == Entity.DeviceId).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ namespace IoTGateway.ViewModel.BasicData.DriverVMs
|
||||
|
||||
public override void DoAdd()
|
||||
{
|
||||
var drvierService = Wtm.ServiceProvider.GetService(typeof(DrvierService)) as DrvierService;
|
||||
Entity.AssembleName = drvierService.GetAssembleNameByFileName(Entity.FileName);
|
||||
var DriverService = Wtm.ServiceProvider.GetService(typeof(DriverService)) as DriverService;
|
||||
Entity.AssembleName = DriverService.GetAssembleNameByFileName(Entity.FileName);
|
||||
if (string.IsNullOrEmpty(Entity.AssembleName))
|
||||
{
|
||||
MSD.AddModelError("", "程序集获取失败");
|
||||
|
@ -78,7 +78,7 @@ namespace IoTGateway.ViewModel.BasicData
|
||||
case FromVM.Device:
|
||||
foreach (var deviceId in Ids)
|
||||
{
|
||||
var device = DC.Set<Device>().AsNoTracking().Include(x => x.Parent).Where(x => x.ID == deviceId).Include(x => x.DeviceVariables).Include(x => x.Driver).SingleOrDefault();
|
||||
var device = DC.Set<Device>().AsNoTracking().Include(x => x.Parent).Where(x => x.ID == deviceId).Include(x => x.DeviceVariables).Include(x => x.Driver).Include(x=>x.DeviceConfigs).SingleOrDefault();
|
||||
if (!devices.Where(x => x.ID == device.ID).Any())
|
||||
devices.Add(device);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace IoTGateway.ViewModel.Config.SystemConfigVMs
|
||||
{
|
||||
base.DoEdit(updateAllFields);
|
||||
var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient;
|
||||
myMqttClient.InitClient();
|
||||
myMqttClient.ConnectAsync();
|
||||
}
|
||||
|
||||
public override void DoDelete()
|
||||
|
@ -280,7 +280,29 @@ namespace IoTGateway.Controllers
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取属性
|
||||
[ActionDescription("获取属性")]
|
||||
public ActionResult Attribute()
|
||||
{
|
||||
var vm = Wtm.CreateVM<AttributeVM>();
|
||||
return PartialView(vm);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ActionDescription("获取属性")]
|
||||
public ActionResult Attribute(AttributeVM vm)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return PartialView(vm);
|
||||
}
|
||||
else
|
||||
{
|
||||
vm.Request();
|
||||
return FFResult().CloseDialog().RefreshGrid().Alert($"{vm.请求结果}");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public IActionResult GetMethods(Guid? ID)
|
||||
{
|
||||
return JsonMore(_DeviceService.GetDriverMethods(ID));
|
||||
|
14
IoTGateway/Areas/BasicData/Views/Device/Attribute.cshtml
Normal file
14
IoTGateway/Areas/BasicData/Views/Device/Attribute.cshtml
Normal file
@ -0,0 +1,14 @@
|
||||
@model IoTGateway.ViewModel.BasicData.DeviceVMs.AttributeVM
|
||||
@inject IStringLocalizer<Program> Localizer;
|
||||
|
||||
|
||||
<wt:form vm="@Model" >
|
||||
<wt:row items-per-row="ItemsPerRowEnum.One">
|
||||
<wt:quote>@Model.设备名称</wt:quote>
|
||||
</wt:row>
|
||||
|
||||
<wt:row align="AlignEnum.Right">
|
||||
<wt:submitbutton text="获取属性" />
|
||||
<wt:closebutton text="取消" />
|
||||
</wt:row>
|
||||
</wt:form>
|
@ -1,10 +1,12 @@
|
||||
@model IoTGateway.ViewModel.BasicData.DeviceConfigVMs.DeviceConfigVM
|
||||
@using IoTGateway.Model
|
||||
@model IoTGateway.ViewModel.BasicData.DeviceConfigVMs.DeviceConfigVM
|
||||
@inject IStringLocalizer<Program> Localizer;
|
||||
|
||||
<wt:form vm="@Model">
|
||||
<wt:row items-per-row="ItemsPerRowEnum.Two">
|
||||
<wt:combobox field="Entity.DeviceId" items="AllDevices"/>
|
||||
<wt:textbox field="Entity.DeviceConfigName" />
|
||||
<wt:combobox field="Entity.DataSide" default-value="@DataSide.ClientSide" />
|
||||
<wt:textbox field="Entity.Description" />
|
||||
<wt:textbox field="Entity.Value" />
|
||||
<wt:textbox field="Entity.EnumInfo" />
|
||||
|
@ -53,21 +53,21 @@ namespace IoTGateway.Controllers
|
||||
|
||||
data.Add(new ChartData
|
||||
{
|
||||
Value = _deviceService.DeviceThreads.Where(x => !x.Device.AutoStart).Count(),
|
||||
Value = _deviceService.DeviceThreads.Where(x => !x._device.AutoStart).Count(),
|
||||
Category = "停止",
|
||||
Series = "Device"
|
||||
});
|
||||
|
||||
data.Add(new ChartData
|
||||
{
|
||||
Value = _deviceService.DeviceThreads.Where(x => x.Device.AutoStart && x.Driver.IsConnected).Count(),
|
||||
Value = _deviceService.DeviceThreads.Where(x => x._device.AutoStart && x._driver.IsConnected).Count(),
|
||||
Category = "运行",
|
||||
Series = "Device",
|
||||
});
|
||||
|
||||
data.Add(new ChartData
|
||||
{
|
||||
Value = _deviceService.DeviceThreads.Where(x => x.Device.AutoStart && !x.Driver.IsConnected).Count(),
|
||||
Value = _deviceService.DeviceThreads.Where(x => x._device.AutoStart && !x._driver.IsConnected).Count(),
|
||||
Category = "异常",
|
||||
Series = "Device"
|
||||
});
|
||||
@ -78,18 +78,18 @@ namespace IoTGateway.Controllers
|
||||
public IActionResult GetDeviceVariableChart()
|
||||
{
|
||||
var data = new List<ChartData>();
|
||||
foreach (var deviceThread in _deviceService.DeviceThreads.OrderBy(x => x.Device.DeviceName))
|
||||
foreach (var deviceThread in _deviceService.DeviceThreads.OrderBy(x => x._device.DeviceName))
|
||||
{
|
||||
data.Add(new ChartData
|
||||
{
|
||||
Category = deviceThread.Device.DeviceName,
|
||||
Category = deviceThread._device.DeviceName,
|
||||
Value = deviceThread.DeviceValues.Where(x => x.Value.StatusType != VaribaleStatusTypeEnum.Good).Count(),
|
||||
Series = "Others"
|
||||
});
|
||||
|
||||
data.Add(new ChartData
|
||||
{
|
||||
Category = deviceThread.Device.DeviceName,
|
||||
Category = deviceThread._device.DeviceName,
|
||||
Value = deviceThread.DeviceValues.Where(x => x.Value.StatusType == VaribaleStatusTypeEnum.Good).Count(),
|
||||
Series = "Good"
|
||||
});
|
||||
|
@ -46,18 +46,20 @@ namespace IoTGateway
|
||||
{
|
||||
options.UseWtmMvcOptions();
|
||||
})
|
||||
.AddJsonOptions(options => {
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.UseWtmJsonOptions();
|
||||
})
|
||||
|
||||
|
||||
.ConfigureApiBehaviorOptions(options =>
|
||||
{
|
||||
options.UseWtmApiOptions();
|
||||
})
|
||||
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
|
||||
.AddWtmDataAnnotationsLocalization(typeof(Program));
|
||||
|
||||
services.AddWtmContext(ConfigRoot, (options)=> {
|
||||
|
||||
services.AddWtmContext(ConfigRoot, (options) =>
|
||||
{
|
||||
options.DataPrivileges = DataPrivilegeSettings();
|
||||
options.CsSelector = CSSelector;
|
||||
options.FileSubDirSelector = SubDirSelector;
|
||||
@ -75,7 +77,7 @@ namespace IoTGateway
|
||||
|
||||
services.AddHostedService<IoTBackgroundService>();
|
||||
services.AddSingleton<DeviceService>();
|
||||
services.AddSingleton<DrvierService>();
|
||||
services.AddSingleton<DriverService>();
|
||||
services.AddSingleton<UAService>();
|
||||
services.AddSingleton<MyMqttClient>();
|
||||
services.AddSingleton<ModbusSlaveService>();
|
||||
@ -137,7 +139,7 @@ namespace IoTGateway
|
||||
|
||||
app.UseWtmContext();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -3,13 +3,13 @@
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
"LogLevel": {
|
||||
"Default": "Error"
|
||||
"Default": "Information"
|
||||
}
|
||||
},
|
||||
"Debug": {
|
||||
"IncludeScopes": true,
|
||||
"LogLevel": {
|
||||
"Default": "Error"
|
||||
"Default": "Information"
|
||||
}
|
||||
},
|
||||
"WTM": {
|
||||
|
Binary file not shown.
@ -16,12 +16,14 @@ using IoTGateway.DataAccess;
|
||||
using IoTGateway.Model;
|
||||
using DynamicExpresso;
|
||||
using MQTTnet.Server;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Plugin
|
||||
{
|
||||
public class DeviceService : IDisposable
|
||||
{
|
||||
public DrvierService _DrvierManager;
|
||||
private readonly ILogger<DeviceService> _logger;
|
||||
public DriverService _DrvierManager;
|
||||
|
||||
public List<DeviceThread> DeviceThreads = new List<DeviceThread>();
|
||||
private MyMqttClient _MyMqttClient;
|
||||
@ -29,9 +31,9 @@ namespace Plugin
|
||||
private string connnectSetting = IoTBackgroundService.connnectSetting;
|
||||
private DBTypeEnum DBType = IoTBackgroundService.DBType;
|
||||
private Interpreter interpreter = new();
|
||||
|
||||
public DeviceService(IConfiguration ConfigRoot, DrvierService drvierManager, MyMqttClient myMqttClient, UAService uAService, IMqttServer mqttServer )
|
||||
public DeviceService(IConfiguration ConfigRoot, DriverService drvierManager, MyMqttClient myMqttClient, UAService uAService, IMqttServer mqttServer, ILogger<DeviceService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_DrvierManager = drvierManager;
|
||||
_MyMqttClient = myMqttClient;
|
||||
_MqttServer = mqttServer;
|
||||
@ -41,6 +43,7 @@ namespace Plugin
|
||||
using (var DC = new DataContext(connnectSetting, DBType))
|
||||
{
|
||||
var Devices = DC.Set<Device>().Where(x => x.DeviceTypeEnum == DeviceTypeEnum.Device).Include(x => x.Parent).Include(x => x.Driver).Include(x => x.DeviceConfigs).Include(x => x.DeviceVariables).AsNoTracking().ToList();
|
||||
_logger.LogInformation($"Loaded Devices Count:{Devices.Count()}");
|
||||
foreach (var Device in Devices)
|
||||
{
|
||||
CreateDeviceThread(Device);
|
||||
@ -50,6 +53,7 @@ namespace Plugin
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
_logger.LogError($"LoadDevicesError", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,12 +61,14 @@ namespace Plugin
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"UpdateDevice Start:{device.DeviceName}");
|
||||
RemoveDeviceThread(device);
|
||||
CreateDeviceThread(device);
|
||||
_logger.LogInformation($"UpdateDevice End:{device.DeviceName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"{device.DeviceName},更新失败");
|
||||
_logger.LogError($"UpdateDevice Error:{device.DeviceName}", ex);
|
||||
}
|
||||
|
||||
}
|
||||
@ -75,13 +81,12 @@ namespace Plugin
|
||||
|
||||
public void CreateDeviceThread(Device Device)
|
||||
{
|
||||
using (var DC = new DataContext(connnectSetting, DBType))
|
||||
try
|
||||
{
|
||||
var systemManage = DC.Set<SystemConfig>().FirstOrDefault();
|
||||
if (systemManage == null)
|
||||
Console.WriteLine("配置信息错误,无法启动");
|
||||
else
|
||||
_logger.LogInformation($"CreateDeviceThread Start:{Device.DeviceName}");
|
||||
using (var DC = new DataContext(connnectSetting, DBType))
|
||||
{
|
||||
var systemManage = DC.Set<SystemConfig>().FirstOrDefault();
|
||||
var driver = _DrvierManager.DriverInfos.Where(x => x.Type.FullName == Device.Driver.AssembleName).SingleOrDefault();
|
||||
var settings = DC.Set<DeviceConfig>().Where(x => x.DeviceId == Device.ID).AsNoTracking().ToList();
|
||||
Type[] types = new Type[1] { typeof(Guid) };
|
||||
@ -137,10 +142,17 @@ namespace Plugin
|
||||
p.SetValue(DeviceObj, value);
|
||||
}
|
||||
|
||||
var deviceThread = new DeviceThread(Device, DeviceObj, systemManage.GatewayName, _MyMqttClient, interpreter, _MqttServer);
|
||||
var deviceThread = new DeviceThread(Device, DeviceObj, systemManage.GatewayName, _MyMqttClient, interpreter, _MqttServer, _logger);
|
||||
DeviceThreads.Add(deviceThread);
|
||||
|
||||
}
|
||||
|
||||
_logger.LogInformation($"CreateDeviceThread End:{Device.DeviceName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogInformation($"CreateDeviceThread Error:{Device.DeviceName}", ex);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -155,7 +167,7 @@ namespace Plugin
|
||||
{
|
||||
if (Device != null)
|
||||
{
|
||||
var DeviceThread = DeviceThreads.Where(x => x.Device.ID == Device.ID).FirstOrDefault();
|
||||
var DeviceThread = DeviceThreads.Where(x => x._device.ID == Device.ID).FirstOrDefault();
|
||||
if (DeviceThread != null)
|
||||
{
|
||||
DeviceThread.StopThread();
|
||||
@ -174,21 +186,32 @@ namespace Plugin
|
||||
public List<ComboSelectListItem> GetDriverMethods(Guid? DeviceId)
|
||||
{
|
||||
List<ComboSelectListItem> driverFilesComboSelect = new List<ComboSelectListItem>();
|
||||
foreach (var method in DeviceThreads.Where(x => x.Device.ID == DeviceId).FirstOrDefault()?.Methods)
|
||||
try
|
||||
{
|
||||
var Attribute = method.CustomAttributes.ToList().FirstOrDefault().ConstructorArguments;
|
||||
var item = new ComboSelectListItem
|
||||
_logger.LogInformation($"GetDriverMethods Start:{DeviceId}");
|
||||
foreach (var method in DeviceThreads.Where(x => x._device.ID == DeviceId).FirstOrDefault()?.Methods)
|
||||
{
|
||||
Text = method.Name,
|
||||
Value = method.Name,
|
||||
};
|
||||
driverFilesComboSelect.Add(item);
|
||||
var Attribute = method.CustomAttributes.ToList().FirstOrDefault().ConstructorArguments;
|
||||
var item = new ComboSelectListItem
|
||||
{
|
||||
Text = method.Name,
|
||||
Value = method.Name,
|
||||
};
|
||||
driverFilesComboSelect.Add(item);
|
||||
}
|
||||
_logger.LogInformation($"GetDriverMethods End:{DeviceId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
_logger.LogInformation($"GetDriverMethods Error:{DeviceId}");
|
||||
}
|
||||
|
||||
return driverFilesComboSelect;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
int t = 0;
|
||||
_logger.LogInformation("Dispose");
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
|
@ -12,13 +12,15 @@ using WalkingTec.Mvvm.Core;
|
||||
using DynamicExpresso;
|
||||
using MQTTnet.Server;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Plugin
|
||||
{
|
||||
public class DeviceThread : IDisposable
|
||||
{
|
||||
public Device Device { get; set; }
|
||||
public IDriver Driver { get; set; }
|
||||
private readonly ILogger _logger;
|
||||
public readonly Device _device;
|
||||
public readonly IDriver _driver;
|
||||
public Dictionary<Guid, DriverReturnValueModel> DeviceValues { get; set; } = new();
|
||||
internal List<MethodInfo> Methods { get; set; }
|
||||
private Task task { get; set; } = null;
|
||||
@ -26,140 +28,141 @@ namespace Plugin
|
||||
private CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||
private Interpreter Interpreter = null;
|
||||
|
||||
public DeviceThread(Device device, IDriver driver, string ProjectId, MyMqttClient myMqttClient, Interpreter interpreter, IMqttServer mqttServer)
|
||||
public DeviceThread(Device device, IDriver driver, string ProjectId, MyMqttClient myMqttClient, Interpreter interpreter, IMqttServer mqttServer, ILogger logger)
|
||||
{
|
||||
Device = device;
|
||||
Driver = driver;
|
||||
_device = device;
|
||||
_driver = driver;
|
||||
Interpreter = interpreter;
|
||||
Methods = Driver.GetType().GetMethods().Where(x => x.GetCustomAttribute(typeof(MethodAttribute)) != null).ToList();
|
||||
if (Device.AutoStart)
|
||||
_logger = logger;
|
||||
Methods = _driver.GetType().GetMethods().Where(x => x.GetCustomAttribute(typeof(MethodAttribute)) != null).ToList();
|
||||
if (_device.AutoStart)
|
||||
{
|
||||
Console.WriteLine($"采集线程已启动:{Device.DeviceName}");
|
||||
_logger.LogInformation($"线程已启动:{_device.DeviceName}");
|
||||
|
||||
using (var DC = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DBType))
|
||||
{
|
||||
if (Device.DeviceVariables != null)
|
||||
if (_device.DeviceVariables != null)
|
||||
{
|
||||
foreach (var item in Device.DeviceVariables)
|
||||
foreach (var item in _device.DeviceVariables)
|
||||
{
|
||||
DeviceValues[item.ID] = new() { StatusType = VaribaleStatusTypeEnum.Bad };
|
||||
}
|
||||
}
|
||||
}
|
||||
myMqttClient.UploadAttributeAsync(device.DeviceName, device.DeviceConfigs.Where(x => x.DataSide == DataSide.ClientSide).ToDictionary(x => x.DeviceConfigName, x => x.Value));
|
||||
|
||||
task = Task.Run(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (tokenSource.IsCancellationRequested)
|
||||
{
|
||||
Console.WriteLine($"{Device.DeviceName},停止线程");
|
||||
return;
|
||||
}
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (tokenSource.IsCancellationRequested)
|
||||
{
|
||||
_logger.LogInformation($"停止线程:{_device.DeviceName}");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, List<PayLoad>> sendModel = new() { { Device.DeviceName, new() } };
|
||||
try
|
||||
{
|
||||
Dictionary<string, List<PayLoad>> sendModel = new() { { _device.DeviceName, new() } };
|
||||
|
||||
var payLoad = new PayLoad() { Values = new() };
|
||||
if (false)//Device.DeviceConfigs != null 配置数据先不上传
|
||||
foreach (var DeviceConfig in Device.DeviceConfigs)
|
||||
payLoad.Values[DeviceConfig.DeviceConfigName] = DeviceConfig.Value;
|
||||
var payLoad = new PayLoad() { Values = new() };
|
||||
|
||||
if (driver.IsConnected)
|
||||
{
|
||||
if (Device.DeviceVariables != null)
|
||||
{
|
||||
foreach (var item in Device.DeviceVariables)
|
||||
{
|
||||
var ret = new DriverReturnValueModel();
|
||||
var ioarg = new DriverAddressIoArgModel
|
||||
{
|
||||
ID = item.ID,
|
||||
Address = item.DeviceAddress,
|
||||
ValueType = item.DataType
|
||||
};
|
||||
var method = Methods.Where(x => x.Name == item.Method).FirstOrDefault();
|
||||
if (method == null)
|
||||
ret.StatusType = VaribaleStatusTypeEnum.MethodError;
|
||||
else
|
||||
ret = (DriverReturnValueModel)method.Invoke(Driver, new object[1] { ioarg });
|
||||
if (driver.IsConnected)
|
||||
{
|
||||
if (_device.DeviceVariables != null)
|
||||
{
|
||||
foreach (var item in _device.DeviceVariables)
|
||||
{
|
||||
var ret = new DriverReturnValueModel();
|
||||
var ioarg = new DriverAddressIoArgModel
|
||||
{
|
||||
ID = item.ID,
|
||||
Address = item.DeviceAddress,
|
||||
ValueType = item.DataType
|
||||
};
|
||||
var method = Methods.Where(x => x.Name == item.Method).FirstOrDefault();
|
||||
if (method == null)
|
||||
ret.StatusType = VaribaleStatusTypeEnum.MethodError;
|
||||
else
|
||||
ret = (DriverReturnValueModel)method.Invoke(_driver, new object[1] { ioarg });
|
||||
|
||||
if (ret.StatusType == VaribaleStatusTypeEnum.Good && !string.IsNullOrWhiteSpace(item.Expressions?.Trim()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ret.CookedValue = interpreter.Eval(DealMysqlStr(item.Expressions).Replace("raw", ret.Value?.ToString()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ret.StatusType = VaribaleStatusTypeEnum.ExpressionError;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret.CookedValue = ret.Value;
|
||||
if (ret.StatusType == VaribaleStatusTypeEnum.Good && !string.IsNullOrWhiteSpace(item.Expressions?.Trim()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ret.CookedValue = interpreter.Eval(DealMysqlStr(item.Expressions).Replace("raw", ret.Value?.ToString()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ret.StatusType = VaribaleStatusTypeEnum.ExpressionError;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret.CookedValue = ret.Value;
|
||||
|
||||
payLoad.Values[item.Name] = ret.CookedValue;
|
||||
payLoad.Values[item.Name] = ret.CookedValue;
|
||||
|
||||
ret.VarId = item.ID;
|
||||
ret.VarId = item.ID;
|
||||
|
||||
//变化了才推送到mqttserver,用于前端展示
|
||||
if (DeviceValues[item.ID].StatusType != ret.StatusType || DeviceValues[item.ID].Value?.ToString() != ret.Value?.ToString() || DeviceValues[item.ID].CookedValue?.ToString() != ret.CookedValue?.ToString())
|
||||
{
|
||||
//这是设备变量列表要用的
|
||||
mqttServer.PublishAsync($"internal/v1/gateway/telemetry/{Device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret));
|
||||
//这是在线组态要用的
|
||||
mqttServer.PublishAsync($"v1/gateway/telemetry/{Device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret.CookedValue));
|
||||
}
|
||||
//变化了才推送到mqttserver,用于前端展示
|
||||
if (DeviceValues[item.ID].StatusType != ret.StatusType || DeviceValues[item.ID].Value?.ToString() != ret.Value?.ToString() || DeviceValues[item.ID].CookedValue?.ToString() != ret.CookedValue?.ToString())
|
||||
{
|
||||
//这是设备变量列表要用的
|
||||
mqttServer.PublishAsync($"internal/v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret));
|
||||
//这是在线组态要用的
|
||||
mqttServer.PublishAsync($"v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret.CookedValue));
|
||||
}
|
||||
|
||||
DeviceValues[item.ID] = ret;
|
||||
DeviceValues[item.ID] = ret;
|
||||
|
||||
}
|
||||
payLoad.TS = (long)(DateTime.Now - TsStartDt).TotalMilliseconds;
|
||||
}
|
||||
payLoad.TS = (long)(DateTime.Now - TsStartDt).TotalMilliseconds;
|
||||
|
||||
if (DeviceValues.Any(x => x.Value.Value ==null))
|
||||
{
|
||||
payLoad.Values = null;
|
||||
payLoad.DeviceStatus = DeviceStatusTypeEnum.Bad;
|
||||
}
|
||||
else
|
||||
{
|
||||
payLoad.DeviceStatus = DeviceStatusTypeEnum.Good;
|
||||
sendModel[Device.DeviceName] = new List<PayLoad> { payLoad };
|
||||
myMqttClient.Publish(Device,sendModel);
|
||||
}
|
||||
}
|
||||
if (DeviceValues.Any(x => x.Value.Value == null))
|
||||
{
|
||||
payLoad.Values = null;
|
||||
payLoad.DeviceStatus = DeviceStatusTypeEnum.Bad;
|
||||
}
|
||||
else
|
||||
{
|
||||
payLoad.DeviceStatus = DeviceStatusTypeEnum.Good;
|
||||
sendModel[_device.DeviceName] = new List<PayLoad> { payLoad };
|
||||
myMqttClient.PublishTelemetry(_device, sendModel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
driver.Connect();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"线程循环异常,{Device.DeviceName},{ex}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
driver.Connect();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"线程循环异常,{_device.DeviceName}", ex);
|
||||
}
|
||||
|
||||
Thread.Sleep((int)Driver.MinPeriod);
|
||||
}
|
||||
});
|
||||
Thread.Sleep((int)_driver.MinPeriod);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void StopThread()
|
||||
{
|
||||
_logger.LogInformation($"线程停止:{_device.DeviceName}");
|
||||
if (task != null)
|
||||
{
|
||||
Driver.Close();
|
||||
_driver.Close();
|
||||
tokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Driver.Dispose();
|
||||
Console.WriteLine($"{Device.DeviceName},释放");
|
||||
_driver.Dispose();
|
||||
_logger.LogInformation($"线程释放,{_device.DeviceName}");
|
||||
}
|
||||
|
||||
//mysql会把一些符号转义,没找到原因,先临时处理下
|
||||
|
@ -11,23 +11,28 @@ using System.Threading.Tasks;
|
||||
using WalkingTec.Mvvm.Core;
|
||||
using IoTGateway.DataAccess;
|
||||
using IoTGateway.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Plugin
|
||||
{
|
||||
public class DrvierService//: IDependency
|
||||
public class DriverService//: IDependency
|
||||
{
|
||||
private readonly ILogger<DriverService> _logger;
|
||||
string DriverPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"drivers/net6.0");
|
||||
string[] driverFiles;
|
||||
public List<DriverInfo> DriverInfos = new List<DriverInfo>();
|
||||
public DrvierService(IConfiguration ConfigRoot)
|
||||
public DriverService(IConfiguration ConfigRoot, ILogger<DriverService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
try
|
||||
{
|
||||
driverFiles = Directory.GetFiles(DriverPath).Where(x => Path.GetExtension(x) == ".dll").ToArray();
|
||||
_logger.LogInformation("LoadDriverFiles Start");
|
||||
driverFiles = Directory.GetFiles(DriverPath).Where(x => Path.GetExtension(x) == ".dll").ToArray();
|
||||
_logger.LogInformation($"LoadDriverFiles End,Count{driverFiles.Count()}");
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
_logger.LogError("LoadDriverFiles Error", ex);
|
||||
}
|
||||
LoadAllDrivers();
|
||||
}
|
||||
@ -91,6 +96,7 @@ namespace Plugin
|
||||
ID = Guid.NewGuid(),
|
||||
DeviceId = dapID,
|
||||
DeviceConfigName = property.Name,
|
||||
DataSide= DataSide.AnySide,
|
||||
Description = ((ConfigParameterAttribute)config).Description,
|
||||
Value = property.GetValue(iObj)?.ToString()
|
||||
};
|
||||
@ -112,6 +118,7 @@ namespace Plugin
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("LoadAllDrivers Start");
|
||||
foreach (var file in driverFiles)
|
||||
{
|
||||
var dll = Assembly.LoadFrom(file);
|
||||
@ -125,10 +132,11 @@ namespace Plugin
|
||||
DriverInfos.Add(driverInfo);
|
||||
}
|
||||
}
|
||||
_logger.LogInformation($"LoadAllDrivers End,Count{DriverInfos.Count}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("驱动加载失败,一般是驱动项目引用的nuget或dll没有复制到驱动文件夹");
|
||||
_logger.LogError("LoadAllDrivers Error,一般是驱动项目引用的nuget或dll没有复制到驱动文件夹", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Modbus.Data;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Modbus.Data;
|
||||
using Modbus.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -12,13 +13,15 @@ namespace Plugin
|
||||
{
|
||||
public class ModbusSlaveService : IDisposable
|
||||
{
|
||||
private readonly ILogger<ModbusSlaveService> _logger;
|
||||
TcpListener slaveTcpListener;
|
||||
private Timer m_simulationTimer;
|
||||
private object Lock=new object();
|
||||
private ModbusSlave slave;
|
||||
private Task task { get; set; } = null;
|
||||
public ModbusSlaveService()
|
||||
public ModbusSlaveService(ILogger<ModbusSlaveService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
byte slaveId = 1;
|
||||
int port = 503;
|
||||
IPAddress address = IPAddress.Any;
|
||||
@ -30,6 +33,7 @@ namespace Plugin
|
||||
slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
|
||||
slave.ListenAsync();
|
||||
m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000);
|
||||
_logger.LogInformation($"Modbus Server Started");
|
||||
}
|
||||
|
||||
private void DoSimulation(object state)
|
||||
@ -53,11 +57,12 @@ namespace Plugin
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"modbus模拟数据失败了,{ex}");
|
||||
_logger.LogError($"Modbus Server Error", ex);
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_logger.LogError($"Modbus Server Dispose");
|
||||
m_simulationTimer.Dispose();
|
||||
slaveTcpListener.Stop();
|
||||
}
|
||||
|
@ -1,91 +1,221 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using IoTGateway.DataAccess;
|
||||
using IoTGateway.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Connecting;
|
||||
using MQTTnet.Client.Disconnecting;
|
||||
using MQTTnet.Client.Options;
|
||||
using MQTTnet.Client.Receiving;
|
||||
using System;
|
||||
using MQTTnet.Protocol;
|
||||
using Newtonsoft.Json;
|
||||
using WalkingTec.Mvvm.Core;
|
||||
using System.Collections.Generic;
|
||||
using IoTGateway.DataAccess;
|
||||
using IoTGateway.Model;
|
||||
using System.Linq;
|
||||
using PluginInterface;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Quickstarts.ReferenceServer;
|
||||
using Opc.Ua;
|
||||
|
||||
namespace Plugin
|
||||
{
|
||||
public class MyMqttClient//: IDependency
|
||||
public class MyMqttClient
|
||||
{
|
||||
private IMqttClient _mqttClient = null;
|
||||
private ReferenceNodeManager _uaNodeManager = null;
|
||||
private MqttClientOptionsBuilder builder = null;
|
||||
private SystemConfig systemConfig = null;
|
||||
public MyMqttClient(UAService uaService)
|
||||
private readonly ILogger<MyMqttClient> _logger;
|
||||
private readonly ReferenceNodeManager _uaNodeManager = null;
|
||||
|
||||
private SystemConfig? _systemConfig;
|
||||
private IMqttClientOptions clientOptions;
|
||||
public bool IsConnected => (Client?.IsConnected).GetValueOrDefault();
|
||||
private IMqttClient Client { get; set; }
|
||||
public event EventHandler<RpcRequest> OnExcRpc;
|
||||
public event EventHandler<AttributeResponse> OnReceiveAttributes;
|
||||
public MyMqttClient(UAService uaService, ILogger<MyMqttClient> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_uaNodeManager = uaService.server.m_server.nodeManagers[0] as ReferenceNodeManager;
|
||||
InitClient();
|
||||
ConnectAsync();
|
||||
}
|
||||
public void InitClient()
|
||||
|
||||
public async Task<bool> ConnectAsync()
|
||||
{
|
||||
bool initok = false;
|
||||
try
|
||||
{
|
||||
using (var DC = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DBType))
|
||||
{
|
||||
_systemConfig = DC.Set<SystemConfig>().FirstOrDefault();
|
||||
if (_systemConfig == null)
|
||||
{
|
||||
_systemConfig = new SystemConfig()
|
||||
{
|
||||
ID = Guid.NewGuid(),
|
||||
GatewayName = "iotgateway",
|
||||
MqttIp = "localhost",
|
||||
MqttPort = 1888,
|
||||
MqttUName = "user",
|
||||
MqttUPwd = "pwd",
|
||||
IoTPlatformType = IoTPlatformType.IoTSharp
|
||||
};
|
||||
DC.Set<SystemConfig>().Add(_systemConfig);
|
||||
DC.SaveChanges();
|
||||
}
|
||||
var factory = new MqttFactory();
|
||||
Client = (MqttClient)factory.CreateMqttClient();
|
||||
clientOptions = new MqttClientOptionsBuilder()
|
||||
.WithClientId(_systemConfig.GatewayName + Guid.NewGuid().ToString())
|
||||
.WithTcpServer(_systemConfig.MqttIp, _systemConfig.MqttPort)
|
||||
.WithCredentials(_systemConfig.MqttUName, _systemConfig.MqttUPwd)
|
||||
.WithCommunicationTimeout(TimeSpan.FromSeconds(30))
|
||||
.WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
|
||||
.Build();
|
||||
|
||||
Client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(Client_ApplicationMessageReceived);
|
||||
Client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(x => OnConnected());
|
||||
Client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(x => OnDisconnectedAsync());
|
||||
try
|
||||
{
|
||||
Client.ConnectAsync(clientOptions);
|
||||
initok = true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError("MQTT CONNECTING FAILED", exception);
|
||||
}
|
||||
_logger.LogInformation("MQTT WAITING FOR APPLICATION MESSAGES");
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError("MQTT CONNECTING FAILED", exception);
|
||||
}
|
||||
return initok;
|
||||
}
|
||||
|
||||
private async Task OnDisconnectedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient != null)
|
||||
_mqttClient.Dispose();
|
||||
await Client.ConnectAsync(clientOptions);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError("MQTT CONNECTING FAILED", exception);
|
||||
}
|
||||
}
|
||||
|
||||
using (var DC = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DBType))
|
||||
private void OnConnected()
|
||||
{
|
||||
Client.SubscribeAsync($"devices/+/rpc/request/+/+", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
Client.SubscribeAsync($"devices/Modbus/attributes/update/", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
Client.SubscribeAsync($"devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
_logger.LogInformation($"MQTT CONNECTED WITH SERVER ");
|
||||
}
|
||||
|
||||
private Task Client_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
|
||||
{
|
||||
_logger.LogDebug($"ApplicationMessageReceived Topic {e.ApplicationMessage.Topic} QualityOfServiceLevel:{e.ApplicationMessage.QualityOfServiceLevel} Retain:{e.ApplicationMessage.Retain} ");
|
||||
try
|
||||
{
|
||||
if (e.ApplicationMessage.Topic.StartsWith($"devices/") && e.ApplicationMessage.Topic.Contains("/response/"))
|
||||
{
|
||||
systemConfig = DC.Set<SystemConfig>().FirstOrDefault();
|
||||
if (systemConfig == null)
|
||||
Console.WriteLine("配置信息错误,无法启动");
|
||||
else
|
||||
ReceiveAttributes(e);
|
||||
}
|
||||
else if (e.ApplicationMessage.Topic.StartsWith($"devices/") && e.ApplicationMessage.Topic.Contains("/rpc/request/"))
|
||||
{
|
||||
var tps = e.ApplicationMessage.Topic.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var rpcmethodname = tps[4];
|
||||
var rpcdevicename = tps[1];
|
||||
var rpcrequestid = tps[5];
|
||||
_logger.LogInformation($"rpcmethodname={rpcmethodname} ");
|
||||
_logger.LogInformation($"rpcdevicename={rpcdevicename } ");
|
||||
_logger.LogInformation($"rpcrequestid={rpcrequestid} ");
|
||||
if (!string.IsNullOrEmpty(rpcmethodname) && !string.IsNullOrEmpty(rpcdevicename) && !string.IsNullOrEmpty(rpcrequestid))
|
||||
{
|
||||
_mqttClient = new MqttFactory().CreateMqttClient();
|
||||
_mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(x => OnConnected());
|
||||
_mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(x => OnDisconnected());
|
||||
_mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnReceived);
|
||||
builder = new MqttClientOptionsBuilder()
|
||||
.WithCommunicationTimeout(TimeSpan.FromSeconds(60))
|
||||
.WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
|
||||
.WithTcpServer(systemConfig.MqttIp, systemConfig.MqttPort)
|
||||
.WithClientId(systemConfig.MqttUName + Guid.NewGuid().ToString())
|
||||
.WithCredentials(systemConfig.MqttUName, systemConfig.MqttUPwd);
|
||||
|
||||
_mqttClient.ConnectAsync(builder.Build());
|
||||
OnExcRpc?.Invoke(Client, new RpcRequest()
|
||||
{
|
||||
Method = rpcmethodname,
|
||||
DeviceId = rpcdevicename,
|
||||
RequestId = rpcrequestid,
|
||||
Params = e.ApplicationMessage.ConvertPayloadToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
_logger.LogError($"ClientId:{e.ClientId} Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}", ex);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Publish(Device device, Dictionary<string, List<PayLoad>> SendModel)
|
||||
private void ReceiveAttributes(MqttApplicationMessageReceivedEventArgs e)
|
||||
{
|
||||
var tps = e.ApplicationMessage.Topic.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var rpcmethodname = tps[2];
|
||||
var rpcdevicename = tps[1];
|
||||
var rpcrequestid = tps[4];
|
||||
_logger.LogInformation($"rpcmethodname={rpcmethodname} ");
|
||||
_logger.LogInformation($"rpcdevicename={rpcdevicename } ");
|
||||
_logger.LogInformation($"rpcrequestid={rpcrequestid} ");
|
||||
|
||||
if (!string.IsNullOrEmpty(rpcmethodname) && !string.IsNullOrEmpty(rpcdevicename) && !string.IsNullOrEmpty(rpcrequestid))
|
||||
{
|
||||
if (e.ApplicationMessage.Topic.Contains("/attributes/"))
|
||||
{
|
||||
OnReceiveAttributes?.Invoke(Client, new AttributeResponse()
|
||||
{
|
||||
KeyName = rpcmethodname,
|
||||
DeviceName = rpcdevicename,
|
||||
Id = rpcrequestid,
|
||||
Data = e.ApplicationMessage.ConvertPayloadToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task UploadAttributeAsync(string _devicename, object obj)
|
||||
{
|
||||
return Client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic($"devices/{_devicename}/attributes").WithPayload(Newtonsoft.Json.JsonConvert.SerializeObject(obj)).Build());
|
||||
}
|
||||
|
||||
public Task UploadTelemetryDataAsync(string _devicename, object obj)
|
||||
{
|
||||
return Client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic($"devices/{_devicename}/telemetry").WithPayload(Newtonsoft.Json.JsonConvert.SerializeObject(obj)).Build());
|
||||
}
|
||||
|
||||
public Task ResponseExecommand(RpcResponse rpcResult)
|
||||
{
|
||||
///IoTSharp/Clients/RpcClient.cs#L65 var responseTopic = $"/devices/{deviceid}/rpc/response/{methodName}/{rpcid}";
|
||||
string topic = $"devices/{rpcResult.DeviceId}/rpc/response/{rpcResult.Method.ToString()}/{rpcResult.ResponseId}";
|
||||
return Client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(rpcResult.Data.ToString()).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build());
|
||||
}
|
||||
|
||||
public Task RequestAttributes(string _device, bool anySide, params string[] args)
|
||||
{
|
||||
string id = Guid.NewGuid().ToString();
|
||||
string topic = $"devices/{_device}/attributes/request/{id}";
|
||||
Dictionary<string, string> keys = new Dictionary<string, string>();
|
||||
keys.Add(anySide ? "anySide" : "server", string.Join(",", args));
|
||||
Client.SubscribeAsync($"devices/{_device}/attributes/response/{id}", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
return Client.PublishAsync(topic, Newtonsoft.Json.JsonConvert.SerializeObject(keys), MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
}
|
||||
|
||||
public void PublishTelemetry(Device device, Dictionary<string, List<PayLoad>> SendModel)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (systemConfig.IoTPlatformType)
|
||||
switch (_systemConfig.IoTPlatformType)
|
||||
{
|
||||
case IoTPlatformType.ThingsBoard:
|
||||
_mqttClient.PublishAsync("v1/gateway/telemetry", JsonConvert.SerializeObject(SendModel));
|
||||
Client.PublishAsync("v1/gateway/telemetry", JsonConvert.SerializeObject(SendModel));
|
||||
break;
|
||||
case IoTPlatformType.IoTSharp:
|
||||
foreach (var payload in SendModel[device.DeviceName])
|
||||
{
|
||||
_mqttClient.PublishAsync($"devices/{device.DeviceName}/telemetry", JsonConvert.SerializeObject(payload.Values));
|
||||
UploadTelemetryDataAsync(device.DeviceName, payload.Values);
|
||||
}
|
||||
break;
|
||||
case IoTPlatformType.AliCloudIoT:
|
||||
case IoTPlatformType.TencentIoTHub:
|
||||
case IoTPlatformType.BaiduIoTCore:
|
||||
case IoTPlatformType.OneNET:
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
foreach (var payload in SendModel[device.DeviceName])
|
||||
@ -93,7 +223,7 @@ namespace Plugin
|
||||
foreach (var kv in payload.Values)
|
||||
{
|
||||
//更新到UAService
|
||||
_uaNodeManager?.UpdateNode($"{device.Parent.DeviceName}.{device.DeviceName}.{kv.Key}", kv.Value);
|
||||
_uaNodeManager.UpdateNode($"{device.Parent.DeviceName}.{device.DeviceName}.{kv.Key}", kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,27 +236,27 @@ namespace Plugin
|
||||
|
||||
}
|
||||
|
||||
private void Update2UAService()
|
||||
{
|
||||
int i = 0;
|
||||
}
|
||||
}
|
||||
public class RpcRequest
|
||||
{
|
||||
public string DeviceId { get; set; }
|
||||
public string Method { get; set; }
|
||||
public string RequestId { get; set; }
|
||||
public string Params { get; set; }
|
||||
}
|
||||
public class RpcResponse
|
||||
{
|
||||
public string DeviceId { get; set; }
|
||||
public string Method { get; set; }
|
||||
public string ResponseId { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
public class AttributeResponse
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string DeviceName { get; set; }
|
||||
public string KeyName { get; set; }
|
||||
|
||||
private void OnReceived(MqttApplicationMessageReceivedEventArgs obj)
|
||||
{
|
||||
var topic = obj.ApplicationMessage.Topic;
|
||||
var msg = System.Text.Encoding.UTF8.GetString(obj.ApplicationMessage.Payload);
|
||||
Console.WriteLine($"{topic}: {msg}");
|
||||
}
|
||||
|
||||
private void OnDisconnected()
|
||||
{
|
||||
Console.WriteLine("Mqtt连接断开");
|
||||
_mqttClient.ConnectAsync(builder.Build());
|
||||
}
|
||||
|
||||
private void OnConnected()
|
||||
{
|
||||
Console.WriteLine("Mqtt连接正常");
|
||||
}
|
||||
public string Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user