Add receiver (not complete)

This commit is contained in:
parallelbgls
2023-10-12 15:16:48 +08:00
parent 511434d18a
commit d23b942464
41 changed files with 1592 additions and 42 deletions

View File

@@ -0,0 +1,36 @@
using Quartz.Logging;
namespace ModbusTcpToRtu
{
// simple log provider to get something to the console
public class ConsoleLogProvider : ILogProvider
{
private readonly IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"}.json", true)
.Build();
public Logger GetLogger(string name)
{
return (level, func, exception, parameters) =>
{
if (level >= configuration.GetSection("Quartz").GetValue<Quartz.Logging.LogLevel>("LogLevel") && func != null)
{
Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
}
return true;
};
}
public IDisposable OpenNestedContext(string message)
{
throw new NotImplementedException();
}
public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-ModbusTcpToRtu-b7b7d9ed-80ce-4790-86de-5c3cf21e0a2e</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj" />
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net\Modbus.Net.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,38 @@
using ModbusTcpToRtu;
using Serilog;
IHost host = Host.CreateDefaultBuilder(args).UseWindowsService()
.ConfigureAppConfiguration((hostingContext, config) =>
{
var configuration = config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"}.json", true)
.AddEnvironmentVariables()
.Build();
Directory.SetCurrentDirectory(hostingContext.HostingEnvironment.ContentRootPath);
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("Log\\log..txt", Serilog.Events.LogEventLevel.Error, shared: true, rollingInterval: RollingInterval.Day)
.CreateLogger();
var loggerFactory = new LoggerFactory().AddSerilog(Log.Logger);
Quartz.Logging.LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
Modbus.Net.LogProvider.SetLogProvider(loggerFactory);
}
)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(Log.Logger, true));
})
.Build();
await host.RunAsync();

View File

@@ -0,0 +1,163 @@
using Modbus.Net;
using Modbus.Net.Modbus;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;
using BaseUtility = Modbus.Net.BaseUtility<byte[], byte[], Modbus.Net.ProtocolUnit<byte[], byte[]>, Modbus.Net.PipeUnit>;
using MultipleMachinesJobScheduler = Modbus.Net.MultipleMachinesJobScheduler<Modbus.Net.IMachineMethodDatas, string, double>;
namespace ModbusTcpToRtu
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private BaseUtility readUtility;
private BaseUtility writeUtility;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var triggerKey = "Modbus.Net.Job.Utility.SchedulerTrigger";
var jobKey = "Modbus.Net.Job.Utility.JobKey";
var intervalMilliSecond = int.Parse(ConfigurationReader.GetValue("Utility", "interval")) * 1000;
var count = int.Parse(ConfigurationReader.GetValue("Utility", "count"));
var readWriteGroup = ConfigurationReader.GetContent<List<ReadWriteGroup>>("Utility", "readwrite");
var readType = Enum.Parse<ModbusType>(ConfigurationReader.GetValue("Utility:read", "type"));
var readAddress = ConfigurationReader.GetValue("Utility:read", "address");
var readSlaveAddress = byte.Parse(ConfigurationReader.GetValue("Utility:read", "slaveAddress"));
var readMasterAddress = byte.Parse(ConfigurationReader.GetValue("Utility:read", "masterAddress"));
var writeType = Enum.Parse<ModbusType>(ConfigurationReader.GetValue("Utility:write", "type"));
var writeAddress = ConfigurationReader.GetValue("Utility:write", "address");
var writeSlaveAddress = byte.Parse(ConfigurationReader.GetValue("Utility:write", "slaveAddress"));
var writeMasterAddress = byte.Parse(ConfigurationReader.GetValue("Utility:write", "masterAddress"));
readUtility = new ModbusUtility(readType, readAddress, readSlaveAddress, readMasterAddress, Endian.BigEndianLsb);
writeUtility = new ModbusUtility(writeType, writeAddress, writeSlaveAddress, writeMasterAddress, Endian.BigEndianLsb);
IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
await scheduler.Start();
ITrigger trigger;
if (intervalMilliSecond <= 0)
{
trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey, "Modbus.Net.DataQuery.Group." + triggerKey)
.StartNow()
.Build();
}
else if (count >= 0)
trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey, "Modbus.Net.DataQuery.Group." + triggerKey)
.StartNow()
.WithSimpleSchedule(b => b.WithInterval(TimeSpan.FromMilliseconds(intervalMilliSecond)).WithRepeatCount(count))
.Build();
else
trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey, "Modbus.Net.DataQuery.Group." + triggerKey)
.StartNow()
.WithSimpleSchedule(b => b.WithInterval(TimeSpan.FromMilliseconds(intervalMilliSecond)).RepeatForever())
.Build();
IJobListener listener;
if (intervalMilliSecond <= 0)
{
listener = new JobChainingJobLIstenerWithDataMapRepeated("Modbus.Net.DataQuery.Chain." + triggerKey, new string[2] { "Value", "SetValue" }, count);
}
else
{
listener = new JobChainingJobListenerWithDataMap("Modbus.Net.DataQuery.Chain." + triggerKey, new string[2] { "Value", "SetValue" });
}
scheduler.ListenerManager.AddJobListener(listener, GroupMatcher<JobKey>.GroupEquals("Modbus.Net.DataQuery.Group." + triggerKey));
if (await scheduler.GetTrigger(new TriggerKey(triggerKey)) != null)
{
await scheduler.UnscheduleJob(new TriggerKey(triggerKey, "Modbus.Net.DataQuery.Group." + triggerKey));
}
var jobKeys = await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals("Modbus.Net.DataQuery.Group." + triggerKey));
await scheduler.DeleteJobs(jobKeys);
var job = JobBuilder.Create<UtilityPassDataJob>()
.WithIdentity(jobKey)
.StoreDurably(true)
.Build();
job.JobDataMap.Put("UtilityRead", readUtility);
job.JobDataMap.Put("UtilityReadWriteGroup", readWriteGroup);
job.JobDataMap.Put("UtilityWrite", writeUtility);
await scheduler.ScheduleJob(job, trigger);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
return Task.Run(() => MultipleMachinesJobScheduler.CancelJob());
}
}
public class UtilityPassDataJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
object utilityReadObject;
object utilityWriteObject;
object utilityReadWriteGroupObject;
context.JobDetail.JobDataMap.TryGetValue("UtilityRead", out utilityReadObject);
context.JobDetail.JobDataMap.TryGetValue("UtilityWrite", out utilityWriteObject);
context.JobDetail.JobDataMap.TryGetValue("UtilityReadWriteGroup", out utilityReadWriteGroupObject);
var readUtility = (BaseUtility)utilityReadObject;
var writeUtility = (BaseUtility)utilityWriteObject;
var utilityReadWriteGroup = (List<ReadWriteGroup>)utilityReadWriteGroupObject;
if (readUtility.IsConnected != true)
await readUtility.ConnectAsync();
if (writeUtility.IsConnected != true)
await writeUtility.ConnectAsync();
foreach (var rwGroup in utilityReadWriteGroup)
{
var datas = await readUtility.GetDatasAsync(rwGroup.ReadStart / 10000 + "X " + rwGroup.ReadStart % 10000, rwGroup.ReadCount * 2);
if (datas.IsSuccess == true)
{
var ans = await writeUtility.SetDatasAsync(rwGroup.WriteStart / 10000 + "X " + rwGroup.WriteStart % 10000, ByteArrayToObjectArray(datas.Datas));
if (ans.Datas)
{
Console.WriteLine("success");
}
}
else
{
Console.WriteLine("failed");
}
}
}
public static object[] ByteArrayToObjectArray(byte[] arrBytes)
{
List<object> objArray = new List<object>();
foreach (byte b in arrBytes)
{
objArray.Add(b);
}
return objArray.ToArray();
}
}
public class ReadWriteGroup
{
public int ReadStart { get; set; }
public int ReadCount { get; set; }
public int WriteStart { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@@ -0,0 +1,53 @@
{
"Modbus.Net": {
"TCP": {
"ConnectionTimeout": "5000",
"FetchSleepTime": "100",
"FullDuplex": "True",
"Modbus": {
"ModbusPort": "502",
"IP": "192.168.1.1"
},
"Siemens": {
"SiemensPort": "102",
"IP": "192.168.1.1"
}
},
"UDP": {
"ConnectionTimeout": "5000",
"FetchSleepTime": "100",
"FullDuplex": "True",
"Modbus": {
"ModbusPort": "502",
"IP": "192.168.1.1"
}
},
"COM": {
"FetchSleepTime": "100",
"ConnectionTimeout": "5000",
"BaudRate": "BaudRate9600",
"Parity": "None",
"StopBits": "One",
"DataBits": "Eight",
"Handshake": "None",
"FullDuplex": "False",
"Modbus": {
"COM": "COM1"
},
"Siemens": {
"COM": "COM2",
"Parity": "Even"
}
},
"OpcDa": {
"Host": "opcda://localhost/test"
},
"OpcUa": {
"Host": "opc.tcp://localhost/test"
},
"Controller": {
"WaitingListCount": "100",
"NoResponse": false
}
}
}

View File

@@ -0,0 +1,55 @@
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Quartz": {
"LogLevel": "Info"
},
"ConnectionStrings": {
"DatabaseWriteConnectionString": "Server=127.0.0.1; User ID=root; Password=123456; Database=modbusnettest;"
},
"Modbus.Net": {
"Utility": {
"interval": 10, //间隔时常(秒)
"count": -1, //不要动
"readwrite": [
{
"readStart": 40001, //读取开始地址
"readCount": 16, //读取字的个数
"writeStart": 40001 //写入开始地址
}, //可以写多个
{
"readStart": 40016, //读取开始地址
"readCount": 16, //读取字的个数
"writeStart": 40016 //写入开始地址
} //可以写多个
],
"read": {
"type": "Tcp",
"address": "127.0.0.1:502", //读取的设备地址
"slaveAddress": 2, //从站地址
"masterAddress": 1 //主站地址
},
"write": {
"type": "Rtu",
"address": "COM2", //写入的设备地址
"slaveAddress": 3, //从站地址
"masterAddress": 1 //主站地址
}
}
}
}