添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
< PropertyGroup > < OutputType > WinExe </ OutputType > < TargetFramework > net6.0-windows </ TargetFramework > < Nullable > enable </ Nullable > < UseWindowsForms > true </ UseWindowsForms > < ImplicitUsings > enable </ ImplicitUsings > </ PropertyGroup > < ItemGroup > < None Include = " ..\.editorconfig " Link = " .editorconfig " /> </ ItemGroup > < ItemGroup > < PackageReference Include = " Microsoft.EntityFrameworkCore " Version = " 6.0.3 " /> < PackageReference Include = " Microsoft.EntityFrameworkCore.Abstractions " Version = " 6.0.3 " /> < PackageReference Include = " Microsoft.EntityFrameworkCore.Relational " Version = " 6.0.3 " /> < PackageReference Include = " Microsoft.EntityFrameworkCore.Sqlite " Version = " 6.0.3 " /> < PackageReference Include = " Microsoft.EntityFrameworkCore.Tools " Version = " 6.0.3 " > < PrivateAssets > all </ PrivateAssets > < IncludeAssets > runtime; build; native; contentfiles; analyzers; buildtransitive </ IncludeAssets > </ PackageReference > < PackageReference Include = " Microsoft.Extensions.Configuration " Version = " 6.0.1 " /> < PackageReference Include = " Microsoft.Extensions.Configuration.Binder " Version = " 6.0.0 " /> < PackageReference Include = " Microsoft.Extensions.Configuration.Json " Version = " 6.0.0 " /> < PackageReference Include = " Microsoft.Extensions.Options " Version = " 6.0.0 " /> < PackageReference Include = " Newtonsoft.Json " Version = " 13.0.1 " /> < PackageReference Include = " NModbus4.NetCore " Version = " 2.0.1 " /> < PackageReference Include = " Pomelo.EntityFrameworkCore.MySql " Version = " 6.0.1 " /> </ ItemGroup > < ItemGroup > < None Update = " VariableNode.json " > < CopyToOutputDirectory > PreserveNewest </ CopyToOutputDirectory > </ None > </ ItemGroup > </ Project >
using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using thinger.DataConvertLib;
namespace EF6Demon
    public class NModBusHelper
        private TcpClient tcpClient = null;
        private ModbusIpMaster master;
        public bool Connect(string ip, string port)
                tcpClient = new TcpClient();
                tcpClient.Connect(IPAddress.Parse(ip), int.Parse(port));
                master = ModbusIpMaster.CreateIp(tcpClient);
            catch (Exception)
                return false;
            return tcpClient.Connected;
        public bool Disconnect()
            if (tcpClient != null)
                tcpClient.Close();
                return true;
                return false;
        public byte[] ReadKeepRegByteArr(string iAddress, string iLength)//偏移量,寄存器数量
                ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
                byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
                return res;
            catch (Exception)
                return null;
        public ushort[] ReadKeepRegUshort(string iAddress, string iLength)//偏移量,寄存器数量
                ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
                //byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
                return des;
            catch (Exception)
                return null;
        public List<float> AnalyseData_4x(ushort[] des, string iAddress)
            int StartByte;
            StartByte = int.Parse(iAddress) * 2;
            List<float> floatArray = new List<float>();
            byte[] byteArray = ByteArrayLib.GetByteArrayFromUShortArray(des);
            for (int i = StartByte; i < byteArray.Length; i += 4)
                floatArray.Add(FloatLib.GetFloatFromByteArray(byteArray, i));
            return floatArray;
using Microsoft.Extensions.Configuration;
using thinger.DataConvertLib;
namespace EF6Demon
    public partial class FrmMain : Form
        public FrmMain()
            InitializeComponent();
            this.Load += FrmMain_Load;
        private ModelsResponsitory dbContext = new ModelsResponsitory();
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        private IConfigurationRoot configRoot;
        private CancellationTokenSource cts = new CancellationTokenSource();
        ushort[] res;
        string iAddress = "0";
        string iLenth; //寄存器个数
        private List<float> floatList = new List<float>();
        private CancellationTokenSource cts1 = new CancellationTokenSource();
        InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
        private NModBusHelper objTcp;
        private void FrmMain_Load(object? sender, EventArgs e)
            //读取IP;
            cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            this.configRoot = cfgBuilder.Build();
            CommonMethods.Ip = configRoot.GetSection("NodeClass:ModbusNode:ServerURL").Value;
            CommonMethods.Port = configRoot.GetSection("NodeClass:ModbusNode:Port").Value;
            CommonMethods.VarNum = configRoot.GetSection("NodeClass:ModbusNode:VarNum").Value;
            //读取点表信息
            //for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
            //    Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
            //    CommonMethods.AllVarList.Add(variable);
            this.iLenth = configRoot.GetSection("NodeClass:ModbusNode:ModbusGroup:Length").Value;
            CommonMethods.ModbusTCPList = dbContext.GetAllVariable();
            foreach (var item in CommonMethods.ModbusTCPList)
                foreach (var item1 in item.ModbusNodes)
                    foreach (var item2 in item1.ModbusGroups)
                        CommonMethods.AllVarList.AddRange(item2.Variables);
            InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
            ModbusTCPInitialInfo();
            Communication();
        private void Communication()
            if (CommonMethods.ModbusTCPList.Count() > 0)
                foreach (var t in CommonMethods.ModbusTCPList)
                    foreach (var dev in t.ModbusNodes)
                        if (bool.Parse(dev.IsActive))
                            Task.Run(async () =>
                                while (!cts1.IsCancellationRequested)
                                    if (CommonMethods.IsConnected)
                                        await Task.Delay(500);
                                        foreach (var gp in dev.ModbusGroups)
                                            if (bool.Parse(gp.IsActive))
                                                //读取数据
                                                byte[] res = null;
                                                if (int.Parse(gp.StoreArea) == 40000)
                                                    res = objTcp.ReadKeepRegByteArr(gp.Start, gp.Length);
                                                if (res != null && res.Length == int.Parse(gp.Length) * 2)
                                                    CommonMethods.ErrorTimes = 0;
                                                    foreach (var variable in gp.Variables)
                                                        if (VerifyModbusAddress(false, variable.VarAddress, out int start, out int offset))
                                                            start -= int.Parse(gp.Start);
                                                            start *= 2;
                                                            // ABCD = 0,BADC = 1, CDAB = 2, DCBA = 3,
                                                            switch (variable.VarType)
                                                                case "Float":
                                                                    variable.Value = FloatLib.GetFloatFromByteArray(res, start, DataFormat.ABCD).ToString();
                                                                    break;
                                                                case "UShort":
                                                                    variable.Value = UShortLib.GetUShortFromByteArray(res, start, DataFormat.ABCD).ToString();
                                                                    break;
                                                                default:
                                                                    break;
                                                            //包含就替换,否则就添加
                                                            if (CommonMethods.CurrentPLCValue.ContainsKey(variable.Name))
                                                                CommonMethods.CurrentPLCValue[variable.Name] = variable.Value;
                                                                CommonMethods.CurrentPLCValue.Add(variable.Name, variable.Value);
                                                    CommonMethods.ErrorTimes++;
                                                    if (CommonMethods.ErrorTimes >= int.Parse(dev.MaxErrorTimes))
                                                        CommonMethods.IsConnected = false;
                                        if (!CommonMethods.FirstConnect)
                                            await Task.Delay(int.Parse(dev.ReConnectTime));
                                            objTcp?.Disconnect();
                                        //第一次 连接
                                        //初始化通信对象
                                        objTcp = new NModBusHelper();
                                        CommonMethods.IsConnected = objTcp.Connect(dev.ServerURL, dev.Port);
                                        CommonMethods.FirstConnect = false;
                                        await Task.Delay(200);
                            }, cts1.Token);
        private void ModbusTCPInitialInfo()
            foreach (var variable in CommonMethods.AllVarList)
                if (!CommonMethods.CurrentPLCVariable.ContainsKey(variable.Name))
                    CommonMethods.CurrentPLCVariable.Add(variable.Name, variable);
                    CommonMethods.CurrentPLCVariable[variable.Name] = variable;
                //存储的归档变量
                if (bool.Parse(variable.ArchiveEnable))
                    CommonMethods.ArchiveVarList.Add(variable);
            //归档变量, 用来查询实时数据, ArchiveEnable的数据要与配置文件SystemSet一致
            foreach (var variable in CommonMethods.ArchiveVarList)
                if (!CommonMethods.CurrentPLCNote.ContainsKey(variable.Name))
                    CommonMethods.CurrentPLCNote.Add(variable.Name, variable.Description);
                    CommonMethods.CurrentPLCNote[variable.Name] = variable.Description;
        private bool VerifyModbusAddress(bool isBit, string address, out int start, out int offset)
            if (isBit)
                offset = 0;
                return int.TryParse(address, out start);
                if (address.Contains('.'))
                    string[] result = address.Split('.');
                    if (result.Length == 2)
                        bool val = true;
                        int res = 0;
                        val = val && int.TryParse(result[0], out res);
                        start = res;
                        val = val && int.TryParse(result[1], out res);
                        offset = res;
                        return val;
                        start = 0;
                        offset = 0;
                        return false;
                    offset = 0;
                    return int.TryParse(address, out start);
        //设置ListBox
        private void Addinfo(string info)
            this.isInfo.Items.Insert(
                0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
        private void btnConn_Click(object sender, EventArgs e)
        private NodeClass nodeClass = new NodeClass();
        private ModbusNode modbusNode = new ModbusNode();
        private ModbusGroup modbusGroup = new ModbusGroup();
        private void btnInsert_Click(object sender, EventArgs e)
            //using (MyDbContext dbContext = new MyDbContext())
            //    this.nodeClass = configRoot.GetSection("NodeClass").Get<NodeClass>();
            //    this.modbusNode = configRoot.GetSection("NodeClass:ModbusNode").Get<ModbusNode>();
            //    this.modbusGroup = configRoot.GetSection("NodeClass:ModbusNode:ModbusGroup").Get<ModbusGroup>();
            //    dbContext.NodeClasses.AddAsync(this.nodeClass);
            //    dbContext.ModbusNodes.AddAsync(this.modbusNode);
            //    dbContext.ModbusGroups.AddAsync(this.modbusGroup);
            //    List<Variable> variables = new List<Variable>();
            //    for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
            //    {
            //        Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
            //        variables.Add(variable);
            //    }
            //    dbContext.Variables.AddRangeAsync(variables);
            //    dbContext.SaveChangesAsync();
        private void btnIn_Click(object sender, EventArgs e)
            //List<ActualData> list = new List<ActualData>();
            ModelsResponsitory db = new ModelsResponsitory();
            this.Dgv.DataSource= db.GetActualData();

插入数据库

using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class InsertDataSQLite
        System.Timers.Timer t;
        int count = 0;
        public InsertDataSQLite(int Interval)
            t = new System.Timers.Timer(Interval);
            t.Elapsed += T_Elapsed;
            t.AutoReset = true;
            t.Enabled = true;
            t.Start();
            count = CommonMethods.CacheCount; //默认为600
        private void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            if (CommonMethods.IsConnected)
                InsertActualData();
        private void InsertActualData()
            if (CommonMethods.CurrentPLCValue != null && CommonMethods.CurrentPLCValue.Count > 0)
                List<ActualData> actualDataArray = new List<ActualData>();
                //List<ReportData> reportDataArray = new List<ReportData>();
                DateTime dt = DateTime.Now;
                foreach (var item in CommonMethods.AllVarList) //FileVarModbusList归档集合
                    string varName = item.Name;//modbus 点表中的名称
                    string description = item.Description; //注释
                    double value = 0;
                    if (!CommonMethods.CurrentPLCValue.ContainsKey(varName))
                        value = 0;
                        value = double.Parse(item.Value);
                        //value = Convert.ToDouble(CommonMethods.CurrentPLCValue[varName]);
                    if (actualDataArray.Count <= 1000)
                        actualDataArray.Add(new ActualData()
                            InsertTime = dt,
                            Name = varName,
                            Value = value.ToString("f2"),
                            Description = description
                        });
                        actualDataArray.RemoveAt(0);
                var db = new ModelsResponsitory();
                db.AddActualData(actualDataArray);
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class CommonMethods
        public static Dictionary<string, object> CurrentPLCValue = new Dictionary<string, object>();
        //归档变量集合
        public static List<Variable> ArchiveVarList = new List<Variable>();
        public static List<Variable> AllVarList = new List<Variable>();
        /// <summary>
        /// 键值对,键是变量名称,值是其对应的变量实体对象 用来写数据
        /// </summary>
        public static Dictionary<string, Variable> CurrentPLCVariable = new Dictionary<string, Variable>();
        /// <summary>
        /// 变量名称和变量地址的键值对
        /// </summary>
        public static Dictionary<string, string> CurrentPLCNote = new Dictionary<string, string>();
        public static bool IsConnected = false;
        public static int CacheCount = 600;//10分钟, 每秒一条
        public static IIncludableQueryable<NodeClass, IEnumerable<Variable>> ModbusTCPList;
        public static int ErrorTimes = 0;
        public static bool FirstConnect = true;
        public static string Ip;
        public static string Port;
        public static string VarNum;

EFcore的配置

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Sqlite;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
namespace EF6Demon
    public class MyDbContext:DbContext
        public DbSet<ActualData> ActualDatas { get; set; } //API中为复数, 而不是数据库表
        public DbSet<NodeClass> NodeClasses { get; set; }
        public DbSet<ModbusNode> ModbusNodes { get; set; }
        public DbSet<ModbusGroup> ModbusGroups { get; set; }
        public DbSet<Variable> Variables { get; set; }
        public DbSet<SysAdmin> SysAdmins { get; set; }
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        //private IConfiguration configuration;
        //private string connString;
        public MyDbContext()
            //configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            base.OnConfiguring(optionsBuilder);
            cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            IConfigurationRoot configRoot = cfgBuilder.Build();
            string connString = configRoot.GetSection("ConnectionStrings:SqliteConnectionString").Value;
            optionsBuilder.UseSqlite(connString);
            //configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
        protected override void OnModelCreating(ModelBuilder modelBuilder)
            base.OnModelCreating(modelBuilder);
            //ConfigurationBuilder cfg1 = new ConfigurationBuilder();
            //cfg1.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            //IConfigurationRoot configRoot = cfg1.Build();
            //string varNum = configRoot.GetSection("NodeClass:ModbusNode:VarNum").Value;
            //IList<Variable> iniVariableList = new List<Variable>();
            //for (int i = 0; i < int.Parse(varNum); i++)
            //    Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
            //    iniVariableList.Add(variable);
            var iniActualData = File.ReadAllText(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"/Database/Variable.json");
            IList<ActualData> iniActualList = JsonConvert.DeserializeObject<IList<ActualData>>(iniActualData);
            //modelBuilder.Entity<Variable>().HasData(iniVariableList);
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    //VS终端下
    // 视图-其他窗口-程序包控制台
    //选择默认项目
    //add-migration initialMigration //创建数据迁移
    //add-migration initialMigration1 //创建数据迁移
    // update-database
    //Remove-migration 删除最后一次脚本
    //Script-Migration 显示迁移的sql脚本
    //DBfirst
    // Scaffold-DbContext "server=192.168.207.107; database=Demon1; uid=root; pwd=123456" Pomelo.EntityFrameworkCore.MySql
    //根据已有数据库创建数据模型。在 NuGet 的程序包管理(Package Manager)控制台中(PowerShell)执行命令:
    //Scaffold-DbContext "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -OutputDir Data -Force
    //.Net Core CLi:dotnet ef dbcontext scaffold "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -o Data -f
    //CMD 命令下 安装EF工具:
    //dotnet tool install --global dotnet-ef
    //数据迁移:
    //dotnet ef migrations add DataSeeding
    //数据更新:
    //dotnet ef database update
     * cmd命令:
     Mysql数据库:
    docker run --name mysqltest -p 3306:3306 -v /usr/local/mysql/data:/var/lib/mysql -v /usr/local/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql
    dotnet ef migrations add MySQLInit
    dotnet ef database update
    dotnet ef database update MySQLUpdate3 回滚 对应版本
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class Variable
        public long Id { get; set; }
        public string Number { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Type { get; set; }
        public string VarAddress { get; set; }
        public string Scale { get; set; }
        public string Offset { get; set; }
        public string Start { get; set; }
        public string AccessProperty { get; set; }
        public string AlarmEnable { get; set; }
        public string ArchiveEnable { get; set; }
        public string SetLimitEnable { get; set; }
        public string AlarmType { get; set; }
        public string DiscreteAlarmType { get; set; }
        public string DiscreteAlarmPriority { get; set; }
        public string DiscreteAlarmNote { get; set; }
        public string LoLoAlarmEnable { get; set; }
        public string LoLoAlarmValue { get; set; }
        public string LoLoAlarmPriority { get; set; }
        public string LoLoAlarmNote { get; set; }
        public string LowAlarmEnable { get; set; }
        public string LowAlarmValue { get; set; }
        public string LowAlarmPriority { get; set; }
        public string LowAlarmNote { get; set; }
        public string HighAlarmEnable { get; set; }
        public string HighAlarmValue { get; set; }
        public string HighAlarmPriority { get; set; }
        public string HighAlarmNote { get; set; }
        public string HiHiAlarmEnable { get; set; }
        public string HiHiAlarmValue { get; set; }
        public string HiHiAlarmPriority { get; set; }
        public string HiHiAlarmNote { get; set; }
        public string ArchivePeriod { get; set; }
        public string SetLimitMax { get; set; }
        public string SetLimitMin { get; set; }
        public string VarType { get; set; }
        public string StoreType { get; set; }
        public string InsertTime { get; set; }
        public string Value { get; set; }
        public long ModbusGroupId { get; set; }
        public ModbusGroup ModbusGroup { get; set; }
using System.Collections.Generic;
namespace EF6Demon
    public class ModbusGroup
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Type { get; set; }
        public string StoreArea { get; set; }
        public string Length { get; set; }
        public string Start { get; set; }
        public string SlaveID { get; set; }
        public string IsActive { get; set; }
        public long ModbusNodeId { get; set; }
        public ModbusNode ModbusNode { get; set; }
        public List<Variable> Variables { get; set; } = new List<Variable>();
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class ModbusNode
        public ModbusNode()
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string ModbusType { get; set; }
        public string ConnectTimeOut { get; set; }
        public string CreateTime { get; set; }
        public string ReConnectTime { get; set; }
        public string IsActive { get; set; }
        public string MaxErrorTimes { get; set; }
        public string KeyWay { get; set; }
        public string UseAlarmCheck { get; set; }
        public string ServerURL { get; set; }
        public string Port { get; set; }
        public string DataFormat { get; set; }
        public string VarNum { get; set; }
        public long NodeClassId { get; set; }
        public List<ModbusGroup> ModbusGroups { get; set; } = new List<ModbusGroup>();
        public NodeClass NodeClass { get; set; }
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class NodeClass
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public List<ModbusNode> ModbusNodes { get; set; } = new List<ModbusNode>();
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class ActualData
        public long Id { get; set; }
        public string Description { get; set; }
        public string Name { get; set; }
        public string Value { get; set; }
        public DateTime InsertTime { get; set; }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF6Demon
    public class SysAdmin
        public long Id { get; set; }
        public string LoginName { get; set; }
        public string Pwd { get; set; }
        public string HandCtrl { get; set; }
        public string AutoCtrl { get; set; }
        public string SysSet { get; set; }
        public string SysLog { get; set; }
        public string Report { get; set; }
        public string Trend { get; set; }
        public string UserManage { get; set; }

模型配置:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    internal class NodeClassConfig : IEntityTypeConfiguration<NodeClass>
        public void Configure(EntityTypeBuilder<NodeClass> builder)
            builder.ToTable("NodeClass");
            builder.HasKey(a => a.Id);
            builder.Property(a => a.Description).HasMaxLength(100);
            builder.HasMany<ModbusNode>(n=>n.ModbusNodes).WithOne(m=> m.NodeClass);
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class ModbusNodeConfig : IEntityTypeConfiguration<ModbusNode>
        public void Configure(EntityTypeBuilder<ModbusNode> builder)
            builder.ToTable("ModbusNode");
            builder.HasKey(a => a.Id);
            builder.Property(a => a.Description).HasMaxLength(100);
            builder.HasOne<NodeClass>(m => m.NodeClass)
                    .WithMany(n => n.ModbusNodes)
                    .HasForeignKey(c => c.NodeClassId);
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class ModbusGroupConfig : IEntityTypeConfiguration<ModbusGroup>
        public void Configure(EntityTypeBuilder<ModbusGroup> builder)
            builder.ToTable("ModbusGroup");
            builder.HasKey(a => a.Id);
            builder.Property(a => a.Description).HasMaxLength(100);
            builder.HasOne<ModbusNode>(c => c.ModbusNode)
                    .WithMany(a => a.ModbusGroups)
                    .HasForeignKey(c => c.ModbusNodeId);
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class VariableConfig : IEntityTypeConfiguration<Variable>
        public void Configure(EntityTypeBuilder<Variable> builder)
            builder.ToTable("Variable");
            builder.HasKey(v => v.Id);
            builder.Property(v => v.Description).HasMaxLength(100);
            builder.HasOne<ModbusGroup>(v => v.ModbusGroup).WithMany(m=>m.Variables).HasForeignKey(v=>v.ModbusGroupId);
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public class ActualDataConfig : IEntityTypeConfiguration<ActualData>
        public void Configure(EntityTypeBuilder<ActualData> builder)
            builder.ToTable("ActualData");
            builder.HasKey(a => a.Id);
            builder.Property(a => a.Description).HasMaxLength(100);
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF6Demon
    public class SysAdminConfig : IEntityTypeConfiguration<SysAdmin>
        public void Configure(EntityTypeBuilder<SysAdmin> builder)
            builder.ToTable("SysAdmins");
            builder.HasKey(a => a.Id);

通过外键, 建立各设备组之间的关系,生成服务类

using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
    public interface IProvider
        List<ActualData> GetActualData();
        void AddActualData(List<ActualData> actualData);
        IIncludableQueryable<NodeClass, IEnumerable<Variable>> GetAllVariable();
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EF6Demon
    public class ModelsResponsitory : IProvider
        private MyDbContext db = new MyDbContext();
        public MyDbContext Db
            get { return db; }
            set { db = value; }
        public void AddActualData(List<ActualData> actualData)
            db.ActualDatas.AddRangeAsync(actualData);
            db.SaveChangesAsync();
        public List<ActualData> GetActualData()
            //IQueryable<ActualData> actualData = db.ActualDatas.Where(a=>a.Id>10);
            //return actualData;
            IEnumerable<ActualData> actualData1 = db.ActualDatas;
            //IEnumerable<TSource> IOrderedEnumerable<TSource> OrderByDescending 全部取出,在内存中比较Where(a => a.Id > 10)
            actualData1.Where(a => a.Id > 10).OrderByDescending(i => i.Id).Take(20);
            //IQueryable<TSource> Where IOrderedQueryable<TSource> OrderByDescending, 给服务器发sql语句 Where(a => a.Id > 10)
            //加上toList 把数据全部取回本地, 不占用带宽
            IQueryable<ActualData> actualData =db.ActualDatas;
            return actualData.Where(a => a.Id > 10).OrderByDescending(i => i.Id).Take(20).ToList(); 
        public IIncludableQueryable<NodeClass, IEnumerable<Variable>> GetAllVariable()
              return db.NodeClasses.
              Include(n => n.ModbusNodes.Where(nodes => nodes.NodeClassId == 1))
              .ThenInclude(m => m.ModbusGroups.Where(groups => groups.ModbusNodeId == 1))
              .ThenInclude(gp => gp.Variables.Where(v => v.ModbusGroupId == 1));

本地配置文件:

"ConnectionStrings": { "SqliteConnectionString": "Data Source=E:\\Csharp\\EF6Demon\\EF6Demon\\bin\\Debug\\net6.0-windows\\Database\\DbSqlite.db", "MySQLConnectionString": "server=192.168.85.102; database=OneToMany; uid=root; pwd=123456;" "NodeClass": { "Id": 1, "Name": "ModbusClent", "Description": "Modbus相关客户端", "ModbusNode": { "Id": 1, "NodeClassId": 1, "Name": "ModbusTCPClient", "Description": "1#ZG上位机测试", "ModbusType": "2000", "ConnectTimeOut": "2000", "CreateTime": "0", "ReConnectTime": "5000", "IsActive": "True", "MaxErrorTimes": "1", "KeyWay": "VarName", "UseAlarmCheck": "True", "ServerURL": "127.0.0.1", "Port": "502", "DataFormat": "ABCD", "VarNum": "6", "ModbusGroup": { "Id": 1, "Name": "保持寄存器长度为寄存器个数", "Description": "40001-40010", "Type": "ModbusTCP", "StoreArea": "40000", "Length": "10", "Start": "0", "SlaveID": "1", "IsActive": "true", "ModbusNodeId": 1, "Variable": [ "Id": 1, "Number": "1", "Name": "Float1", "Description": "40001-40002", "Type": "ModbusTCP", "VarAddress": 0, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40001-40002低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40001-40002低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40001-40002高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40001-40002高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "Float", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 "Id": 2, "Number": "2", "Name": "Float2", "Description": "40003-40004", "Type": "ModbusTCP", "VarAddress": 2, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40003-40004低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40003-40004低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40003-40004高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40003-40004高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "Float", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 "Id": 3, "Number": "3", "Name": "Float3", "Description": "40005-40006", "Type": "ModbusTCP", "VarAddress": 4, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40005-40006低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40005-40006低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40005-40006高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40005-40006高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "Float", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 "Id": 4, "Number": "4", "Name": "Float4", "Description": "40007-40008", "Type": "ModbusTCP", "VarAddress": 6, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40003-40004低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40003-40004低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40003-40004高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40003-40004高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "Float", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 "Id": 5, "Number": "5", "Name": "Ushort1", "Description": "40009", "Type": "ModbusTCP", "VarAddress": 8, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40009低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40009低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40009高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40009高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "UShort", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 "Id": 6, "Number": "6", "Name": "Ushort2", "Description": "40010", "Type": "ModbusTCP", "VarAddress": 9, "Scale": "1", "Offset": "0", "Start": "0", "AccessProperty": "读写", "AlarmEnable": "True", "ArchiveEnable": "True", "SetLimitEnable": "True", "AlarmType": "True", "DiscreteAlarmType": "False", "DiscreteAlarmPriority": "0", "DiscreteAlarmNote": "null", "LoLoAlarmEnable": "True", "LoLoAlarmValue": "0", "LoLoAlarmPriority": "0", "LoLoAlarmNote": "40009低低报警", "LowAlarmEnable": "True", "LowAlarmValue": "20", "LowAlarmPriority": "0", "LowAlarmNote": "40009低报警", "HighAlarmEnable": "True", "HighAlarmValue": "80", "HighAlarmPriority": "0", "HighAlarmNote": "40009高报警", "HiHiAlarmEnable": "True", "HiHiAlarmValue": "100", "HiHiAlarmPriority": "0", "HiHiAlarmNote": "40009高高报警", "ArchivePeriod": "80", "SetLimitMax": "100", "SetLimitMin": "0", "VarType": "UShort", "StoreType": "03 Holding Register(4x)", "InsertTime": "0", "Value": "0", "ModbusGroupId": 1 所用的包:&lt;Project Sdk="Microsoft.NET.Sdk"&gt; &lt;PropertyGroup&gt; &lt;OutputType&gt;WinExe&lt;/OutputType&gt; &lt;TargetFramework&gt;net6.0-windows&lt;/TargetFramework&gt; &lt;Nullable&gt;enable&lt;/Nullable&gt; &lt;UseWindowsForms&gt; private ModbusFactory modbusFactory; private IModbusMaster master; private TcpClient tcpClient; public string IPAdress { get; set; } public int Port { get; set; } public bo
Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。 ModbusTCP的数据帧可分为两部分:MBAP+PDU。 MBAP为报文头,长度为7字节,组成如下:事务处理标识+协议标识+长度+单元标识
Tips:   1、目前NetCore下与Modbus通信的框架主要选择了Modbus.Net https://github.com/parallelbgls/Modbus.Net   2、modbus是常用的工业通信协议,在软件调试时可以通过modbus poll+slave模拟通信通过达到调试目的,下图是我使用软件 1)为串口模拟工具
NModbus is a C# implementation of the Modbus protocol. Provides connectivity to Modbus slave compatible devices and applications. Supports serial ASCII, serial RTU, TCP, and UDP protocols. NModbus4 it's a fork of NModbus(https://code.google.com/p/nmodbus). NModbus4 differs from original NModbus in following: 1.removed USB support(FtdAdapter.dll) 2.removed log4net dependency 3.removed Unme.Common.dll dependency 4.assembly renamed to NModbus4.dll 5.target framework changed to .NET 4
警告:DataConversionWarning: Data was converted to boolean for metric jaccard。warnings.warn(msg, DataConversionWarning) 解释:DataConversionWarning:数据已转换为度量jaccard的布尔值警告.warn(消息,数据转换警告) MODBUS TCP 03功能码报文解析 初识Modbus TCP-------------C#编写Modbus TCP客户端程序(一) 初识Modbus TCP-------------C#编写Modbus TCP客户端程序(二) 0. 软件描述 目前此上位机软件一共有四个版本: 上位机软件v1.0版本功能:可以设置服务器的IP地址与端口号。客户端只能发送固定的报文,并接收服务器返回的报文,若要改变发送的报文,需要在程序中进行更改。 上位机软件v1.1版本功能:在v1.0基础上增加了
二、Modbus 1.最近在做Modbus有关的工作,根据杨更更的 Modbus软件开发实战  里面都是基于VS的很适合我这种C#开发人员,首先根据书里面的介绍LiModbus直接敲代码就OK,敲完自行测试哈,这里就暂时不多缀余。这个是基于C++ 2.Nmodbus这个是基于C#开源的代码 网上也有先下载下来再说https://git...
web 编写遵循的核心协议就是http/tcp 协议。而这个核心的内容是就Socket编程。 Socket 是点对点的通讯模式,是全双工的。是靠IP地址进行寻址访问的。 根据设计又几种模式: 点对点 (适合两者之间大文件的传输) 服务器模式(聊天,webapi等) 这里主要讨论: 服务器模式 Socket 编程需要引用 using System.Net;using System.Ne...