Change projects to .net 6.0
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Quartz.Jobs" Version="3.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj" />
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
81
Modbus.Net/Modbus.Net.Modbus.Test/Program.cs
Normal file
81
Modbus.Net/Modbus.Net.Modbus.Test/Program.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
using Modbus.Net;
|
||||
using Modbus.Net.Modbus;
|
||||
using Modbus.Net.Interface;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
|
||||
List<AddressUnit> _addresses = new List<AddressUnit>
|
||||
{
|
||||
new AddressUnit() { Area = "4X", Address = 1, DataType = typeof(short), Id = "1", Name = "Test1" },
|
||||
new AddressUnit() { Area = "4X", Address = 2, DataType = typeof(short), Id = "2", Name = "Test2" },
|
||||
new AddressUnit() { Area = "4X", Address = 3, DataType = typeof(short), Id = "3", Name = "Test3" },
|
||||
new AddressUnit() { Area = "4X", Address = 4, DataType = typeof(short), Id = "4", Name = "Test4" },
|
||||
new AddressUnit() { Area = "4X", Address = 5, DataType = typeof(short), Id = "5", Name = "Test5" },
|
||||
new AddressUnit() { Area = "4X", Address = 6, DataType = typeof(short), Id = "6", Name = "Test6" },
|
||||
new AddressUnit() { Area = "4X", Address = 7, DataType = typeof(short), Id = "7", Name = "Test7" },
|
||||
new AddressUnit() { Area = "4X", Address = 8, DataType = typeof(short), Id = "8", Name = "Test8" },
|
||||
new AddressUnit() { Area = "4X", Address = 9, DataType = typeof(short), Id = "9", Name = "Test9" },
|
||||
new AddressUnit() { Area = "4X", Address = 10, DataType = typeof(short), Id = "10", Name = "Test10" }
|
||||
};
|
||||
|
||||
IMachine<string> machine = new ModbusMachine<string, string>("ModbusMachine1", ModbusType.Tcp, "192.168.0.172:502", _addresses, true, 2, 1, Endian.BigEndianLsb);
|
||||
|
||||
|
||||
//1.首先创建一个作业调度池
|
||||
ISchedulerFactory schedf = new StdSchedulerFactory();
|
||||
//2.实例化调度器工厂
|
||||
ISchedulerFactory schedulefactory = new StdSchedulerFactory();
|
||||
//3.实例化调度器
|
||||
IScheduler scheduler = await schedulefactory.GetScheduler();
|
||||
|
||||
//4.创建一个作业
|
||||
IJobDetail job1 = JobBuilder.Create<Class1>()
|
||||
.WithIdentity("demojob1", "groupa")
|
||||
.Build();
|
||||
|
||||
//5.1:第一种方法直接写死多少秒执行一次
|
||||
//ITrigger trigger1 = TriggerBuilder.Create()//创建一个触发器
|
||||
// .WithIdentity("demotrigger1", "groupa")
|
||||
// .StartNow()
|
||||
// .WithSimpleSchedule(b => b.WithIntervalInSeconds(5)//5秒执行一次
|
||||
// .RepeatForever())//无限循环执行
|
||||
// .Build();
|
||||
|
||||
//5.2推荐:第二种使用cron表达式
|
||||
//在线生成cron表达式: http://cron.qqe2.com/
|
||||
string corn = "*/5 * * * * ?";
|
||||
ITrigger trigger1 = TriggerBuilder.Create()
|
||||
.WithIdentity("demotrigger1", "groupa")
|
||||
.WithCronSchedule(corn)//每一小时执行一次
|
||||
.Build();
|
||||
|
||||
//6.添加参数(键值对),如果不需要传参则忽略这一步
|
||||
//方法内获取你传的参数: string Name = context.Trigger.JobDataMap.GetString("Name");
|
||||
trigger1.JobDataMap.Add("Machine", machine);
|
||||
|
||||
//7.把作业,触发器加入调度器
|
||||
await scheduler.ScheduleJob(job1, trigger1);
|
||||
//8.开始运行
|
||||
await scheduler.Start();
|
||||
|
||||
Console.ReadLine();
|
||||
|
||||
public class Class1 : IJob
|
||||
{
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
object machine;
|
||||
context.Trigger.JobDataMap.TryGetValue("Machine", out machine);
|
||||
var values = await (machine as IMachine<string>)!.GetDatasAsync(MachineGetDataType.Name);
|
||||
if (values != null)
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
Console.WriteLine(value.Key + " " + value.Value.PlcValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<AssemblyName>Modbus.Net.Modbus</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Modbus</RootNamespace>
|
||||
<PackageId>Modbus.Net.Modbus</PackageId>
|
||||
@@ -11,7 +11,6 @@
|
||||
<Product>Modbus.Net.Modbus</Product>
|
||||
<Description>Modbus.Net Modbus Implementation</Description>
|
||||
<Copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</Copyright>
|
||||
<PackageLicenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</PackageLicenseUrl>
|
||||
<PackageProjectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.Modbus</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/parallelbgls/Modbus.Net</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
@@ -20,31 +19,14 @@
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.Modbus.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="packages.config" />
|
||||
<None Remove="package-lock.json" />
|
||||
<None Remove="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45' ">
|
||||
<Reference Include="System.Configuration" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Modbus.Net.Modbus")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Modbus.Net")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("07bcb9ac-a522-4348-8774-2825fd8a6e64")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.0.1")]
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc地址编码器
|
||||
/// </summary>
|
||||
public class AddressFormaterOpc<TMachineKey, TUnitKey> : AddressFormater where TMachineKey : IEquatable<TMachineKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议构造器
|
||||
/// </summary>
|
||||
/// <param name="tagGeter">如何通过BaseMachine和AddressUnit构造Opc的标签</param>
|
||||
/// <param name="machine">调用这个编码器的设备</param>
|
||||
/// <param name="seperator">每两个标签之间用什么符号隔开,默认为/</param>
|
||||
public AddressFormaterOpc(Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> tagGeter,
|
||||
BaseMachine<TMachineKey, TUnitKey> machine,
|
||||
char seperator = '/')
|
||||
{
|
||||
Machine = machine;
|
||||
TagGeter = tagGeter;
|
||||
Seperator = seperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备
|
||||
/// </summary>
|
||||
public BaseMachine<TMachineKey, TUnitKey> Machine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签构造器
|
||||
/// (设备,地址)->不具备分隔符的标签数组
|
||||
/// </summary>
|
||||
protected Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> TagGeter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分割符
|
||||
/// </summary>
|
||||
public char Seperator { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址所在的数据区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public override string FormatAddress(string area, int address)
|
||||
{
|
||||
var findAddress = Machine?.GetAddresses.FirstOrDefault(p => p.Area == area && p.Address == address);
|
||||
if (findAddress == null) return null;
|
||||
var strings = TagGeter(Machine, findAddress);
|
||||
var ans = "";
|
||||
for (var i = 0; i < strings.Length; i++)
|
||||
ans += strings[i].Trim().Replace(" ", "") + '\r';
|
||||
ans = ans.Substring(0, ans.Length - 1);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址所在的数据区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <param name="subAddress">子地址(忽略)</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public override string FormatAddress(string area, int address, int subAddress)
|
||||
{
|
||||
return FormatAddress(area, address);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc地址解析器
|
||||
/// </summary>
|
||||
public class AddressTranslatorOpc : AddressTranslator
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址转换
|
||||
/// </summary>
|
||||
/// <param name="address">格式化的地址</param>
|
||||
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
|
||||
/// <returns>翻译后的地址</returns>
|
||||
public override AddressDef AddressTranslate(string address, bool isRead)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取区域中的单个地址占用的字节长度
|
||||
/// </summary>
|
||||
/// <param name="area">区域名称</param>
|
||||
/// <returns>字节长度</returns>
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Hylasoft.Opc.Common;
|
||||
using Hylasoft.Opc.Da;
|
||||
using Hylasoft.Opc.Ua;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Client Extend interface, Unified for DA and UA
|
||||
/// </summary>
|
||||
public interface IClientExtend : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Unified Root Node
|
||||
/// </summary>
|
||||
Node RootNodeBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Connect the client to the OPC Server
|
||||
/// </summary>
|
||||
void Connect();
|
||||
|
||||
/// <summary>
|
||||
/// Read a tag
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of tag to read</typeparam>
|
||||
/// <param name="tag">
|
||||
/// The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name.
|
||||
/// E.g: the tag `foo.bar` reads the tag `bar` on the folder `foo`
|
||||
/// </param>
|
||||
/// <returns>The value retrieved from the OPC</returns>
|
||||
ReadEvent<T> Read<T>(string tag);
|
||||
|
||||
/// <summary>
|
||||
/// Write a value on the specified opc tag
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of tag to write on</typeparam>
|
||||
/// <param name="tag">
|
||||
/// The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name.
|
||||
/// E.g: the tag `foo.bar` writes on the tag `bar` on the folder `foo`
|
||||
/// </param>
|
||||
/// <param name="item"></param>
|
||||
void Write<T>(string tag, T item);
|
||||
|
||||
/// <summary>
|
||||
/// Read a tag asynchronusly
|
||||
/// </summary>
|
||||
Task<ReadEvent<T>> ReadAsync<T>(string tag);
|
||||
|
||||
/// <summary>
|
||||
/// Write a value on the specified opc tag asynchronously
|
||||
/// </summary>
|
||||
Task WriteAsync<T>(string tag, T item);
|
||||
|
||||
/// <summary>
|
||||
/// Finds a node on the Opc Server asynchronously
|
||||
/// </summary>
|
||||
Task<Node> FindNodeAsync(string tag);
|
||||
|
||||
/// <summary>
|
||||
/// Explore a folder on the Opc Server asynchronously
|
||||
/// </summary>
|
||||
Task<IEnumerable<Node>> ExploreFolderAsync(string tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UaClient Extend
|
||||
/// </summary>
|
||||
public class MyDaClient : DaClient, IClientExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// UaClient Extend
|
||||
/// </summary>
|
||||
/// <param name="serverUrl">Url address of Opc UA server</param>
|
||||
public MyDaClient(Uri serverUrl) : base(serverUrl)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unified root node
|
||||
/// </summary>
|
||||
public Node RootNodeBase => RootNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DaClient Extend
|
||||
/// </summary>
|
||||
public class MyUaClient : UaClient, IClientExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// DaClient Extend
|
||||
/// </summary>
|
||||
public MyUaClient(Uri serverUrl) : base(serverUrl)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unified root node
|
||||
/// </summary>
|
||||
public Node RootNodeBase => RootNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Param input of OpcConnector
|
||||
/// </summary>
|
||||
public class OpcParamIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Is the action read (not is write)
|
||||
/// </summary>
|
||||
public bool IsRead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tag of a node
|
||||
/// </summary>
|
||||
public string[] Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tag splitter of a node
|
||||
/// </summary>
|
||||
public char Split { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The value set to node(only available when IsRead is false
|
||||
/// </summary>
|
||||
public object SetValue { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Param output of OpcConnector
|
||||
/// </summary>
|
||||
public class OpcParamOut
|
||||
{
|
||||
/// <summary>
|
||||
/// Is the action success
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action return values
|
||||
/// </summary>
|
||||
public byte[] Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Modbus.Net.OPC.FBox
|
||||
{
|
||||
/// <summary>
|
||||
/// FBox的Opc服务设备
|
||||
/// </summary>
|
||||
public class FBoxOpcDaMachine : OpcDaMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="localSequence">页名称</param>
|
||||
/// <param name="linkerName">设备名称</param>
|
||||
/// <param name="getAddresses">获取地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
public FBoxOpcDaMachine(string id, string localSequence, string linkerName,
|
||||
IEnumerable<AddressUnit> getAddresses, bool keepConnect)
|
||||
: base(id,
|
||||
ConfigurationManager.AppSettings["FBoxOpcDaHost"] ?? "opcda://localhost/FBoxOpcServer", getAddresses,
|
||||
keepConnect, true)
|
||||
{
|
||||
LocalSequence = localSequence;
|
||||
LinkerName = linkerName;
|
||||
AddressFormater =
|
||||
new AddressFormaterOpc<string, string>(
|
||||
(machine, unit) =>
|
||||
new[]
|
||||
{
|
||||
"(.*)", ((FBoxOpcDaMachine) machine).LinkerName, ((FBoxOpcDaMachine) machine).LocalSequence,
|
||||
unit.Name
|
||||
}, this, '.');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="localSequence">页名称</param>
|
||||
/// <param name="linkerName">设备名称</param>
|
||||
/// <param name="getAddresses">获取地址</param>
|
||||
public FBoxOpcDaMachine(string id, string localSequence, string linkerName,
|
||||
IEnumerable<AddressUnit> getAddresses)
|
||||
: this(id, localSequence, linkerName, getAddresses, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 页名称
|
||||
/// </summary>
|
||||
public string LocalSequence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string LinkerName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net45</TargetFramework>
|
||||
<AssemblyName>Modbus.Net.OPC</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.OPC</RootNamespace>
|
||||
<PackageId>Modbus.Net.OPC</PackageId>
|
||||
<Version>1.4.1</Version>
|
||||
<Authors>Chris L.(Luo Sheng)</Authors>
|
||||
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
|
||||
<Description>Modbus.Net OPC Implementation</Description>
|
||||
<Copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</Copyright>
|
||||
<PackageProjectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.OPC</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</PackageLicenseUrl>
|
||||
<RepositoryUrl>https://github.com/parallelbgls/Modbus.Net</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>hardware communicate protocal OPC DA Delian</PackageTags>
|
||||
<PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
|
||||
<PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.OPC.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="packages.config" />
|
||||
<None Remove="package-lock.json" />
|
||||
<None Remove="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="H.Opc" Version="0.9.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Configuration" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,205 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Hylasoft.Opc.Common;
|
||||
using Serilog;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc连接器
|
||||
/// </summary>
|
||||
public abstract class OpcConnector : IConnector<OpcParamIn, OpcParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在连接
|
||||
/// </summary>
|
||||
protected bool _connect;
|
||||
|
||||
/// <summary>
|
||||
/// Opc客户端
|
||||
/// </summary>
|
||||
protected IClientExtend Client;
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启正则匹配
|
||||
/// </summary>
|
||||
protected bool RegexOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">服务端url</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
protected OpcConnector(string host, bool isRegexOn)
|
||||
{
|
||||
ConnectionToken = host;
|
||||
RegexOn = isRegexOn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接标识
|
||||
/// </summary>
|
||||
public virtual string ConnectionToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在连接
|
||||
/// </summary>
|
||||
public virtual bool IsConnected => _connect;
|
||||
|
||||
/// <summary>
|
||||
/// 断开连接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
Client?.Dispose();
|
||||
Client = null;
|
||||
_connect = false;
|
||||
Log.Information("opc client {ConnectionToken} disconnected success", ConnectionToken);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "opc client {ConnectionToken} disconnected error", ConnectionToken);
|
||||
_connect = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带返回发送数据
|
||||
/// </summary>
|
||||
/// <param name="message">需要发送的数据</param>
|
||||
/// <returns>是否发送成功</returns>
|
||||
public virtual async Task<OpcParamOut> SendMsgAsync(OpcParamIn message)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (message.IsRead)
|
||||
{
|
||||
var split = message.Split;
|
||||
var tag = message.Tag;
|
||||
var rootDirectory = await Client.ExploreFolderAsync("");
|
||||
var answerTag = await SearchTag(tag, split, 0, rootDirectory);
|
||||
if (answerTag != null)
|
||||
{
|
||||
var result = await Client.ReadAsync<object>(answerTag);
|
||||
Log.Verbose($"Opc Machine {ConnectionToken} Read opc tag {answerTag} for value {result.Value}");
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = true,
|
||||
Value = BigEndianValueHelper.Instance.GetBytes(result.Value, result.Value.GetType())
|
||||
};
|
||||
}
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = false,
|
||||
Value = Encoding.ASCII.GetBytes("NoData")
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var tag = message.Tag;
|
||||
var split = message.Split;
|
||||
var value = message.SetValue;
|
||||
|
||||
var rootDirectory = await Client.ExploreFolderAsync("");
|
||||
var answerTag = await SearchTag(tag, split, 0, rootDirectory);
|
||||
if (answerTag != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Client.WriteAsync(answerTag, value);
|
||||
Log.Verbose($"Opc Machine {ConnectionToken} Write opc tag {answerTag} for value {value}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "opc client {ConnectionToken} write exception", ConnectionToken);
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = true
|
||||
};
|
||||
}
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "opc client {ConnectionToken} read exception", ConnectionToken);
|
||||
return new OpcParamOut
|
||||
{
|
||||
Success = false,
|
||||
Value = Encoding.ASCII.GetBytes("NoData")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索标签
|
||||
/// </summary>
|
||||
/// <param name="tags">标签</param>
|
||||
/// <param name="split">分隔符</param>
|
||||
/// <param name="deep">递归深度(第几级标签)</param>
|
||||
/// <param name="nodes">当前搜索的节点</param>
|
||||
/// <returns>搜索到的标签</returns>
|
||||
private async Task<string> SearchTag(string[] tags, char split, int deep, IEnumerable<Node> nodes)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
var currentTag = node.Tag.Substring(node.Tag.LastIndexOf(split) + 1);
|
||||
if (RegexOn && Regex.IsMatch(currentTag, tags[deep]) || !RegexOn && currentTag == tags[deep])
|
||||
{
|
||||
if (deep == tags.Length - 1) return node.Tag;
|
||||
var subDirectories = await Client.ExploreFolderAsync(node.Tag);
|
||||
var answerTag = await SearchTag(tags, split, deep + 1, subDirectories);
|
||||
if (answerTag != null) return answerTag;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接PLC
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
protected bool Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
Client.Connect();
|
||||
_connect = true;
|
||||
Log.Information("opc client {ConnectionToken} connect success", ConnectionToken);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "opc client {ConnectionToken} connected failed", ConnectionToken);
|
||||
_connect = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接PLC,异步
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public virtual Task<bool> ConnectAsync()
|
||||
{
|
||||
return Task.FromResult(Connect());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc DA连接实现
|
||||
/// </summary>
|
||||
public class OpcDaConnector : OpcConnector
|
||||
{
|
||||
/// <summary>
|
||||
/// DA单例管理
|
||||
/// </summary>
|
||||
protected static Dictionary<string, OpcDaConnector> _instances = new Dictionary<string, OpcDaConnector>();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc DA 服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
protected OpcDaConnector(string host, bool isRegexOn) : base(host, isRegexOn)
|
||||
{
|
||||
Client = new MyDaClient(new Uri(ConnectionToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据服务地址生成DA单例
|
||||
/// </summary>
|
||||
/// <param name="host">Opc DA 服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
/// <returns>Opc DA 连接器实例</returns>
|
||||
public static OpcDaConnector Instance(string host, bool isRegexOn)
|
||||
{
|
||||
if (!_instances.ContainsKey(host))
|
||||
{
|
||||
var connector = new OpcDaConnector(host, isRegexOn);
|
||||
_instances.Add(host, connector);
|
||||
}
|
||||
return _instances[host];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc DA设备
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备Id类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备包含的地址的Id类型</typeparam>
|
||||
public class OpcDaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaMachine(TKey id, string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, bool isRegexOn = false)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
BaseUtility = new OpcDaUtility(connectionString, isRegexOn);
|
||||
((OpcUtility) BaseUtility).GetSeperator +=
|
||||
() => ((AddressFormaterOpc<TKey, TUnitKey>) AddressFormater).Seperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
public OpcDaMachine(TKey id, string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
|
||||
: this(id, connectionString, getAddresses, false)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opc DA设备
|
||||
/// </summary>
|
||||
public class OpcDaMachine : OpcMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaMachine(string id, string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect, bool isRegexOn = false)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
BaseUtility = new OpcDaUtility(connectionString, isRegexOn);
|
||||
((OpcUtility) BaseUtility).GetSeperator +=
|
||||
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
public OpcDaMachine(string id, string connectionString, IEnumerable<AddressUnit> getAddresses)
|
||||
: this(id, connectionString, getAddresses, false)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Da协议
|
||||
/// </summary>
|
||||
public class OpcDaProtocol : OpcProtocol
|
||||
{
|
||||
private readonly string _host;
|
||||
|
||||
private readonly bool _isRegexOn;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc DA服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaProtocol(string host, bool isRegexOn)
|
||||
{
|
||||
_host = host;
|
||||
_isRegexOn = isRegexOn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
ProtocolLinker = new OpcDaProtocolLinker(_host, _isRegexOn);
|
||||
if (!await ProtocolLinker.ConnectAsync())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Da协议连接器
|
||||
/// </summary>
|
||||
public class OpcDaProtocolLinker : OpcProtocolLinker
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaProtocolLinker(bool isRegexOn) : this(ConfigurationManager.AppSettings["OpcDaHost"], isRegexOn)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc DA服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaProtocolLinker(string host, bool isRegexOn)
|
||||
{
|
||||
BaseConnector = OpcDaConnector.Instance(host, isRegexOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Da协议Api入口
|
||||
/// </summary>
|
||||
public class OpcDaUtility : OpcUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcDaUtility(string connectionString, bool isRegexOn = false) : base(connectionString)
|
||||
{
|
||||
Wrapper = new OpcDaProtocol(ConnectionString, isRegexOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Da设备
|
||||
/// </summary>
|
||||
public abstract class OpcMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要读写的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
protected OpcMachine(TKey id, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
AddressCombiner = new AddressCombinerSingle<TUnitKey>();
|
||||
AddressCombinerSet = new AddressCombinerSingle<TUnitKey>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opc Da设备
|
||||
/// </summary>
|
||||
public abstract class OpcMachine : BaseMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要读写的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
protected OpcMachine(string id, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
AddressCombiner = new AddressCombinerSingle();
|
||||
AddressCombinerSet = new AddressCombinerSingle();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc协议
|
||||
/// </summary>
|
||||
public abstract class OpcProtocol : BaseProtocol<OpcParamIn, OpcParamOut, ProtocolUnit<OpcParamIn, OpcParamOut>,
|
||||
PipeUnit<OpcParamIn, OpcParamOut, IProtocolLinker<OpcParamIn, OpcParamOut>,
|
||||
ProtocolUnit<OpcParamIn, OpcParamOut>>>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
protected OpcProtocol() : base(0, 0, Endian.BigEndianLsb)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region 读数据
|
||||
|
||||
/// <summary>
|
||||
/// 读数据输入
|
||||
/// </summary>
|
||||
public class ReadRequestOpcInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="tag">标签</param>
|
||||
/// <param name="split">分隔符</param>
|
||||
public ReadRequestOpcInputStruct(string[] tag, char split)
|
||||
{
|
||||
Tag = tag;
|
||||
Split = split;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public string[] Tag { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 分隔符
|
||||
/// </summary>
|
||||
public char Split { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读地址输出
|
||||
/// </summary>
|
||||
public class ReadRequestOpcOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="value">读取的数据</param>
|
||||
public ReadRequestOpcOutputStruct(byte[] value)
|
||||
{
|
||||
GetValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取的地址
|
||||
/// </summary>
|
||||
public byte[] GetValue { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读数据协议
|
||||
/// </summary>
|
||||
[SpecialProtocolUnit]
|
||||
public class ReadRequestOpcProtocol : ProtocolUnit<OpcParamIn, OpcParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 从对象的参数数组格式化
|
||||
/// </summary>
|
||||
/// <param name="message">非结构化的输入数据</param>
|
||||
/// <returns>格式化后的字节流</returns>
|
||||
public override OpcParamIn Format(IInputStruct message)
|
||||
{
|
||||
var r_message = (ReadRequestOpcInputStruct) message;
|
||||
return new OpcParamIn
|
||||
{
|
||||
IsRead = true,
|
||||
Tag = r_message.Tag,
|
||||
Split = r_message.Split
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把仪器返回的内容填充到输出结构中
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">返回数据的字节流</param>
|
||||
/// <param name="pos">转换标记位</param>
|
||||
/// <returns>结构化的输出数据</returns>
|
||||
public override IOutputStruct Unformat(OpcParamOut messageBytes, ref int pos)
|
||||
{
|
||||
return new ReadRequestOpcOutputStruct(messageBytes.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 写数据
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输入
|
||||
/// </summary>
|
||||
public class WriteRequestOpcInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="tag">标签</param>
|
||||
/// <param name="split">分隔符</param>
|
||||
/// <param name="setValue">写入的数据</param>
|
||||
public WriteRequestOpcInputStruct(string[] tag, char split, object setValue)
|
||||
{
|
||||
Tag = tag;
|
||||
Split = split;
|
||||
SetValue = setValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public string[] Tag { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 分隔符
|
||||
/// </summary>
|
||||
public char Split { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入的数据
|
||||
/// </summary>
|
||||
public object SetValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输出
|
||||
/// </summary>
|
||||
public class WriteRequestOpcOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="writeResult">写入是否成功</param>
|
||||
public WriteRequestOpcOutputStruct(bool writeResult)
|
||||
{
|
||||
WriteResult = writeResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入是否成功
|
||||
/// </summary>
|
||||
public bool WriteResult { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据协议
|
||||
/// </summary>
|
||||
[SpecialProtocolUnit]
|
||||
public class WriteRequestOpcProtocol : ProtocolUnit<OpcParamIn, OpcParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 从对象的参数数组格式化
|
||||
/// </summary>
|
||||
/// <param name="message">非结构化的输入数据</param>
|
||||
/// <returns>格式化后的字节流</returns>
|
||||
public override OpcParamIn Format(IInputStruct message)
|
||||
{
|
||||
var r_message = (WriteRequestOpcInputStruct) message;
|
||||
return new OpcParamIn
|
||||
{
|
||||
IsRead = false,
|
||||
Tag = r_message.Tag,
|
||||
Split = r_message.Split,
|
||||
SetValue = r_message.SetValue
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把仪器返回的内容填充到输出结构中
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">返回数据的字节流</param>
|
||||
/// <param name="pos">转换标记位</param>
|
||||
/// <returns>结构化的输出数据</returns>
|
||||
public override IOutputStruct Unformat(OpcParamOut messageBytes, ref int pos)
|
||||
{
|
||||
var ansByte = BigEndianValueHelper.Instance.GetByte(messageBytes.Value, ref pos);
|
||||
var ans = ansByte != 0;
|
||||
return new WriteRequestOpcOutputStruct(ans);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc协议连接器
|
||||
/// </summary>
|
||||
public abstract class OpcProtocolLinker : ProtocolLinker<OpcParamIn, OpcParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public override async Task<OpcParamOut> SendReceiveAsync(OpcParamIn content)
|
||||
{
|
||||
var extBytes = BytesExtend(content);
|
||||
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
||||
return receiveBytes == null
|
||||
? null
|
||||
: receiveBytes.Value.Length == 0 ? receiveBytes : BytesDecact(receiveBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public override async Task<OpcParamOut> SendReceiveWithoutExtAndDecAsync(OpcParamIn content)
|
||||
{
|
||||
//发送数据
|
||||
var receiveBytes = await BaseConnector.SendMsgAsync(content);
|
||||
//容错处理
|
||||
var checkRight = CheckRight(receiveBytes);
|
||||
return checkRight == null
|
||||
? new OpcParamOut {Success = false, Value = new byte[0]}
|
||||
: (!checkRight.Value ? null : receiveBytes);
|
||||
//返回字符
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查接收的数据是否正确
|
||||
/// </summary>
|
||||
/// <param name="content">接收协议的内容</param>
|
||||
/// <returns>协议是否是正确的</returns>
|
||||
public override bool? CheckRight(OpcParamOut content)
|
||||
{
|
||||
if (content == null || !content.Success) return false;
|
||||
if (content.Value.Length == 6 && Encoding.ASCII.GetString(content.Value) == "NoData")
|
||||
return null;
|
||||
return base.CheckRight(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc UA连接实现
|
||||
/// </summary>
|
||||
public class OpcUaConnector : OpcConnector
|
||||
{
|
||||
/// <summary>
|
||||
/// UA单例管理
|
||||
/// </summary>
|
||||
protected static Dictionary<string, OpcUaConnector> _instances = new Dictionary<string, OpcUaConnector>();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc UA 服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
protected OpcUaConnector(string host, bool isRegexOn) : base(host, isRegexOn)
|
||||
{
|
||||
Client = new MyUaClient(new Uri(ConnectionToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据地址获取UA连接器单例
|
||||
/// </summary>
|
||||
/// <param name="host">Opc UA服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
/// <returns>OPC UA实例</returns>
|
||||
public static OpcUaConnector Instance(string host, bool isRegexOn)
|
||||
{
|
||||
if (!_instances.ContainsKey(host))
|
||||
{
|
||||
var connector = new OpcUaConnector(host, isRegexOn);
|
||||
_instances.Add(host, connector);
|
||||
}
|
||||
return _instances[host];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc UA设备
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备Id的类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备中地址的Id的类型</typeparam>
|
||||
public class OpcUaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaMachine(TKey id, string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, bool isRegexOn = false)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
BaseUtility = new OpcUaUtility(connectionString, isRegexOn);
|
||||
((OpcUtility) BaseUtility).GetSeperator +=
|
||||
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
public OpcUaMachine(TKey id, string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
|
||||
: this(id, connectionString, getAddresses, false)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opc UA设备
|
||||
/// </summary>
|
||||
public class OpcUaMachine : OpcMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaMachine(string id, string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect, bool isRegexOn = false)
|
||||
: base(id, getAddresses, keepConnect)
|
||||
{
|
||||
BaseUtility = new OpcUaUtility(connectionString, isRegexOn);
|
||||
((OpcUtility) BaseUtility).GetSeperator +=
|
||||
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的数据</param>
|
||||
public OpcUaMachine(string id, string connectionString, IEnumerable<AddressUnit> getAddresses)
|
||||
: this(id, connectionString, getAddresses, false)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc UA协议
|
||||
/// </summary>
|
||||
public class OpcUaProtocol : OpcProtocol
|
||||
{
|
||||
private readonly string _host;
|
||||
|
||||
private readonly bool _isRegexOn;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc UA服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaProtocol(string host, bool isRegexOn)
|
||||
{
|
||||
_host = host;
|
||||
_isRegexOn = isRegexOn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
ProtocolLinker = new OpcUaProtocolLinker(_host, _isRegexOn);
|
||||
if (!await ProtocolLinker.ConnectAsync()) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc UA协议连接器
|
||||
/// </summary>
|
||||
public class OpcUaProtocolLinker : OpcProtocolLinker
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaProtocolLinker(bool isRegexOn) : this(ConfigurationManager.AppSettings["OpcUaHost"], isRegexOn)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="host">Opc UA服务地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaProtocolLinker(string host, bool isRegexOn)
|
||||
{
|
||||
BaseConnector = OpcUaConnector.Instance(host, isRegexOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc Ua协议Api入口
|
||||
/// </summary>
|
||||
public class OpcUaUtility : OpcUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="isRegexOn">是否开启正则匹配</param>
|
||||
public OpcUaUtility(string connectionString, bool isRegexOn = false) : base(connectionString)
|
||||
{
|
||||
Wrapper = new OpcUaProtocol(ConnectionString, isRegexOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
|
||||
namespace Modbus.Net.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Opc通用Api入口
|
||||
/// </summary>
|
||||
public abstract class OpcUtility : BaseUtility<OpcParamIn, OpcParamOut, ProtocolUnit<OpcParamIn, OpcParamOut>,
|
||||
PipeUnit<OpcParamIn, OpcParamOut, IProtocolLinker<OpcParamIn, OpcParamOut>,
|
||||
ProtocolUnit<OpcParamIn, OpcParamOut>>>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取分隔符
|
||||
/// </summary>
|
||||
/// <returns>分隔符</returns>
|
||||
public delegate char GetSeperatorDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
protected OpcUtility(string connectionString) : base(0, 0)
|
||||
{
|
||||
ConnectionString = connectionString;
|
||||
AddressTranslator = new AddressTranslatorOpc();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 端格式(大端)
|
||||
/// </summary>
|
||||
public override Endian Endian => Endian.BigEndianLsb;
|
||||
|
||||
/// <summary>
|
||||
/// 获取分隔符
|
||||
/// </summary>
|
||||
public event GetSeperatorDelegate GetSeperator;
|
||||
|
||||
/// <summary>
|
||||
/// 设置连接方式(Opc忽略该函数)
|
||||
/// </summary>
|
||||
/// <param name="connectionType">连接方式</param>
|
||||
public override void SetConnectionType(int connectionType)
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getByteCount">获取字节数个数</param>
|
||||
/// <returns>接收到的byte数据</returns>
|
||||
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var split = GetSeperator?.Invoke() ?? '/';
|
||||
var readRequestOpcInputStruct = new ReadRequestOpcInputStruct(startAddress.Split('\r'), split);
|
||||
var readRequestOpcOutputStruct =
|
||||
await
|
||||
Wrapper.SendReceiveAsync<ReadRequestOpcOutputStruct>(Wrapper[typeof(ReadRequestOpcProtocol)],
|
||||
readRequestOpcInputStruct);
|
||||
return readRequestOpcOutputStruct?.GetValue;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, $"OpcUtility -> GetDatas: {ConnectionString} error");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="setContents">设置数据</param>
|
||||
/// <returns>是否设置成功</returns>
|
||||
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
|
||||
{
|
||||
try
|
||||
{
|
||||
var split = GetSeperator?.Invoke() ?? '/';
|
||||
var writeRequestOpcInputStruct =
|
||||
new WriteRequestOpcInputStruct(startAddress.Split('\r'), split, setContents[0]);
|
||||
var writeRequestOpcOutputStruct =
|
||||
await
|
||||
Wrapper.SendReceiveAsync<WriteRequestOpcOutputStruct>(Wrapper[typeof(WriteRequestOpcProtocol)],
|
||||
writeRequestOpcInputStruct);
|
||||
return writeRequestOpcOutputStruct?.WriteResult == true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, $"OpcUtility -> SetDatas: {ConnectionString} error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Modbus.Net.OPC")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Modbus.Net")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("07bcb9ac-a522-4348-8774-2825fd8a6e64")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.0.1")]
|
||||
@@ -1,7 +0,0 @@
|
||||
Modbus.Net.OPC
|
||||
===================
|
||||
[](https://www.nuget.org/packages/Modbus.Net.OPC/)
|
||||
|
||||
OPC Implementation of Modbus.Net
|
||||
|
||||
Doc has been moved to wiki.
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<AssemblyName>Modbus.Net.Siemens</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Siemens</RootNamespace>
|
||||
<PackageId>Modbus.Net.Siemens</PackageId>
|
||||
@@ -10,7 +10,6 @@
|
||||
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
|
||||
<Description>Modbus.Net Siemens Profinet Implementation</Description>
|
||||
<Copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</Copyright>
|
||||
<PackageLicenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</PackageLicenseUrl>
|
||||
<PackageProjectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.Siemens</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/parallelbgls/Modbus.Net</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
@@ -19,32 +18,15 @@
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.Siemens.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="packages.config" />
|
||||
<None Remove="package-lock.json" />
|
||||
<None Remove="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45' ">
|
||||
<Reference Include="System.Configuration" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Modbus.Net.Siemens")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Modbus.Net")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("07bcb9ac-a522-4348-8774-2825fd8a6e64")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.0.1")]
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2010
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33213.308
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net", "Modbus.Net\Modbus.Net.csproj", "{124EBEF2-8960-4447-84CF-1D683B1EF7CC}"
|
||||
EndProject
|
||||
@@ -14,24 +14,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.Modbus", "Modbus
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.Siemens", "Modbus.Net.Siemens\Modbus.Net.Siemens.csproj", "{6258F9D9-0DF4-497F-9F3B-6D2F6F752A21}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.OPC", "Modbus.Net.OPC\Modbus.Net.OPC.csproj", "{97F5A329-357A-4813-BAAE-58E71CC6FA87}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{145DA93A-6768-4D98-8512-AB22339933F7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D8DD32FC-CF39-4A1A-8FBF-9E82C5278C34}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripleAdd", "..\Samples\TripleAdd\TripleAdd.csproj", "{01E58447-6833-4C10-8ED8-F9DFC3F8E668}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus.Net.Tests", "..\Tests\Modbus.Net.Tests\Modbus.Net.Tests.csproj", "{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskManager", "..\Samples\TaskManager\TaskManager.csproj", "{2D939825-8459-438A-AC82-4C67A73E373E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrossLamp", "..\Samples\CrossLamp\CrossLamp.csproj", "{41F40C27-AB1A-4153-BBAD-BFC7BD57B380}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnyType", "..\Samples\AnyType\AnyType.csproj", "{25FABD48-D82E-4E08-91A4-46F7057EC954}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.Tests", "..\Tests\Modbus.Net.Tests\Modbus.Net.Tests.csproj", "{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.PersistedTests", "..\Tests\Modbus.Net.PersistedTests\Modbus.Net.PersistedTests.csproj", "{EC184EF4-81C4-4A4B-8763-79AC4150E613}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus.Net.Modbus.Test", "Modbus.Net.Modbus.Test\Modbus.Net.Modbus.Test.csproj", "{3615E574-1A98-4BBC-8C08-01FE95AD40AF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -50,45 +42,26 @@ Global
|
||||
{6258F9D9-0DF4-497F-9F3B-6D2F6F752A21}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6258F9D9-0DF4-497F-9F3B-6D2F6F752A21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6258F9D9-0DF4-497F-9F3B-6D2F6F752A21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97F5A329-357A-4813-BAAE-58E71CC6FA87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97F5A329-357A-4813-BAAE-58E71CC6FA87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97F5A329-357A-4813-BAAE-58E71CC6FA87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97F5A329-357A-4813-BAAE-58E71CC6FA87}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{01E58447-6833-4C10-8ED8-F9DFC3F8E668}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{01E58447-6833-4C10-8ED8-F9DFC3F8E668}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{01E58447-6833-4C10-8ED8-F9DFC3F8E668}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{01E58447-6833-4C10-8ED8-F9DFC3F8E668}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3BB01E98-3D45-454A-A1BD-49D7B2C83B74}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2D939825-8459-438A-AC82-4C67A73E373E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2D939825-8459-438A-AC82-4C67A73E373E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2D939825-8459-438A-AC82-4C67A73E373E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2D939825-8459-438A-AC82-4C67A73E373E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{41F40C27-AB1A-4153-BBAD-BFC7BD57B380}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{41F40C27-AB1A-4153-BBAD-BFC7BD57B380}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{41F40C27-AB1A-4153-BBAD-BFC7BD57B380}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{41F40C27-AB1A-4153-BBAD-BFC7BD57B380}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{25FABD48-D82E-4E08-91A4-46F7057EC954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{25FABD48-D82E-4E08-91A4-46F7057EC954}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{25FABD48-D82E-4E08-91A4-46F7057EC954}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{25FABD48-D82E-4E08-91A4-46F7057EC954}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EC184EF4-81C4-4A4B-8763-79AC4150E613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EC184EF4-81C4-4A4B-8763-79AC4150E613}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC184EF4-81C4-4A4B-8763-79AC4150E613}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC184EF4-81C4-4A4B-8763-79AC4150E613}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3615E574-1A98-4BBC-8C08-01FE95AD40AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3615E574-1A98-4BBC-8C08-01FE95AD40AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3615E574-1A98-4BBC-8C08-01FE95AD40AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3615E574-1A98-4BBC-8C08-01FE95AD40AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{01E58447-6833-4C10-8ED8-F9DFC3F8E668} = {145DA93A-6768-4D98-8512-AB22339933F7}
|
||||
{3BB01E98-3D45-454A-A1BD-49D7B2C83B74} = {D8DD32FC-CF39-4A1A-8FBF-9E82C5278C34}
|
||||
{2D939825-8459-438A-AC82-4C67A73E373E} = {145DA93A-6768-4D98-8512-AB22339933F7}
|
||||
{41F40C27-AB1A-4153-BBAD-BFC7BD57B380} = {145DA93A-6768-4D98-8512-AB22339933F7}
|
||||
{25FABD48-D82E-4E08-91A4-46F7057EC954} = {145DA93A-6768-4D98-8512-AB22339933F7}
|
||||
{EC184EF4-81C4-4A4B-8763-79AC4150E613} = {D8DD32FC-CF39-4A1A-8FBF-9E82C5278C34}
|
||||
{3615E574-1A98-4BBC-8C08-01FE95AD40AF} = {3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {AF00D64E-3C70-474A-8A81-E9E48017C4B5}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//Machine Builder. Build a machine without constructor.
|
||||
//MachineBuiler.CreateMachine.(SetAddresses.SetFormatter.SetCombiner).(CreateUtility.SetTranslator).SetEndian.SetProtocolGroups.SetLinker.SetConector.SetController.Build
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Builder
|
||||
{
|
||||
public class MachineBuilder
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -92,8 +92,17 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public abstract class BaseConnector<TParamIn, TParamOut> : IConnector<TParamIn, TParamOut> where TParamIn : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据返回代理参数
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public delegate MessageReturnCallbackArgs<TParamIn> MessageReturnDelegate(object sender, MessageReturnArgs<TParamOut> args);
|
||||
|
||||
/// <summary>
|
||||
/// 数据返回代理
|
||||
/// </summary>
|
||||
public event MessageReturnDelegate MessageReturn;
|
||||
|
||||
/// <summary>
|
||||
@@ -141,6 +150,11 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
protected abstract void ReceiveMsgThreadStop();
|
||||
|
||||
/// <summary>
|
||||
/// 数据返回代理函数
|
||||
/// </summary>
|
||||
/// <param name="receiveMessage"></param>
|
||||
/// <returns></returns>
|
||||
protected TParamIn InvokeReturnMessage(TParamOut receiveMessage)
|
||||
{
|
||||
return MessageReturn?.Invoke(this, new MessageReturnArgs<TParamOut>{ReturnMessage = receiveMessage})?.SendMessage;
|
||||
|
||||
@@ -6,15 +6,28 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据返回代理参数
|
||||
/// </summary>
|
||||
/// <typeparam name="TParamOut"></typeparam>
|
||||
public class MessageReturnArgs<TParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回的数据
|
||||
/// </summary>
|
||||
public TParamOut ReturnMessage { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 数据发送代理参数
|
||||
/// </summary>
|
||||
/// <typeparam name="TParamIn"></typeparam>
|
||||
public class MessageReturnCallbackArgs<TParamIn>
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送的数据
|
||||
/// </summary>
|
||||
public TParamIn SendMessage { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
16
Modbus.Net/Modbus.Net/Interface/IMachine.cs
Normal file
16
Modbus.Net/Modbus.Net/Interface/IMachine.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Interface
|
||||
{
|
||||
public interface IMachine : IMachine<string>
|
||||
{
|
||||
}
|
||||
|
||||
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData where TKey : IEquatable<TKey>
|
||||
{
|
||||
}
|
||||
}
|
||||
77
Modbus.Net/Modbus.Net/Interface/IMachineProperty.cs
Normal file
77
Modbus.Net/Modbus.Net/Interface/IMachineProperty.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 没有Id的设备属性
|
||||
/// </summary>
|
||||
public interface IMachinePropertyWithoutKey
|
||||
{
|
||||
/// <summary>
|
||||
/// 工程名
|
||||
/// </summary>
|
||||
string ProjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备名
|
||||
/// </summary>
|
||||
string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识设备的连接关键字
|
||||
/// </summary>
|
||||
string ConnectionToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于连接状态
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否保持连接
|
||||
/// </summary>
|
||||
bool KeepConnect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备的连接器
|
||||
/// </summary>
|
||||
IUtilityProperty BaseUtility { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备的方法集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TMachineMethod">方法集合的类型</typeparam>
|
||||
/// <returns>设备的方法集合</returns>
|
||||
TMachineMethod GetMachineMethods<TMachineMethod>() where TMachineMethod : class, IMachineMethod;
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
Task<bool> ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 断开设备
|
||||
/// </summary>
|
||||
/// <returns>是否断开成功</returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备的Id的字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetMachineIdString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备的抽象
|
||||
/// </summary>
|
||||
public interface IMachineProperty<TKey> : IMachinePropertyWithoutKey where TKey : IEquatable<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
TKey Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Builder
|
||||
namespace Modbus.Net.Interface
|
||||
{
|
||||
public class UtilityBuilder
|
||||
public interface IUtility : IUtilityProperty, IUtilityMethodData
|
||||
{
|
||||
}
|
||||
}
|
||||
53
Modbus.Net/Modbus.Net/Interface/IUtilityProperty.cs
Normal file
53
Modbus.Net/Modbus.Net/Interface/IUtilityProperty.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Api入口的抽象
|
||||
/// </summary>
|
||||
public interface IUtilityProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议是否遵循小端格式
|
||||
/// </summary>
|
||||
Endian Endian { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备是否已经连接
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识设备的连接关键字
|
||||
/// </summary>
|
||||
string ConnectionToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址翻译器
|
||||
/// </summary>
|
||||
AddressTranslator AddressTranslator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>设备是否连接成功</returns>
|
||||
Task<bool> ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 断开设备
|
||||
/// </summary>
|
||||
/// <returns>设备是否断开成功</returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 返回Utility的方法集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtilityMethod">Utility方法集合类型</typeparam>
|
||||
/// <returns>Utility方法集合</returns>
|
||||
TUtilityMethod GetUtilityMethods<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Modbus.Net.Interface;
|
||||
using Serilog;
|
||||
|
||||
namespace Modbus.Net
|
||||
@@ -128,7 +129,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachineMethodData, IMachineProperty<TKey>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
@@ -209,6 +210,8 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
private IEnumerable<AddressUnit<TUnitKey>> getAddresses;
|
||||
|
||||
private object getAddressesLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 描述需要与设备通讯的地址
|
||||
/// </summary>
|
||||
@@ -220,7 +223,7 @@ namespace Modbus.Net
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (getAddresses)
|
||||
lock (getAddressesLock)
|
||||
{
|
||||
getAddresses = value;
|
||||
}
|
||||
@@ -847,76 +850,4 @@ namespace Modbus.Net
|
||||
return Area.ToUpper() == other.Area.ToUpper() && Address == other.Address || Id.Equals(other.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 没有Id的设备属性
|
||||
/// </summary>
|
||||
public interface IMachinePropertyWithoutKey
|
||||
{
|
||||
/// <summary>
|
||||
/// 工程名
|
||||
/// </summary>
|
||||
string ProjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备名
|
||||
/// </summary>
|
||||
string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识设备的连接关键字
|
||||
/// </summary>
|
||||
string ConnectionToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于连接状态
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否保持连接
|
||||
/// </summary>
|
||||
bool KeepConnect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备的连接器
|
||||
/// </summary>
|
||||
IUtilityProperty BaseUtility { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备的方法集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TMachineMethod">方法集合的类型</typeparam>
|
||||
/// <returns>设备的方法集合</returns>
|
||||
TMachineMethod GetMachineMethods<TMachineMethod>() where TMachineMethod : class, IMachineMethod;
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
Task<bool> ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 断开设备
|
||||
/// </summary>
|
||||
/// <returns>是否断开成功</returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备的Id的字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetMachineIdString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备的抽象
|
||||
/// </summary>
|
||||
public interface IMachineProperty<TKey> : IMachinePropertyWithoutKey where TKey : IEquatable<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
TKey Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<AssemblyName>Modbus.Net</AssemblyName>
|
||||
<RootNamespace>Modbus.Net</RootNamespace>
|
||||
<PackageId>Modbus.Net</PackageId>
|
||||
@@ -9,7 +9,6 @@
|
||||
<Product>Modbus.Net</Product>
|
||||
<Authors>Chris L.(Luo Sheng)</Authors>
|
||||
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
|
||||
<PackageLicenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</PackageLicenseUrl>
|
||||
<PackageProjectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/parallelbgls/Modbus.Net/</RepositoryUrl>
|
||||
<Description>High extensible hardware communication implementation platform.</Description>
|
||||
@@ -20,6 +19,7 @@
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
@@ -27,39 +27,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="packages.config" />
|
||||
<None Remove="package-lock.json" />
|
||||
<None Remove="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog" Version="2.5.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45' ">
|
||||
<PackageReference Include="Nito.AsyncEx" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45' ">
|
||||
<Reference Include="System.Configuration" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Nito.AsyncEx.Tasks" Version="1.1.0" />
|
||||
<PackageReference Include="Nito.AsyncEx.Coordination" Version="1.0.2" />
|
||||
<PackageReference Include="System.Collections.NonGeneric" Version="4.3.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
|
||||
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Modbus.Net")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Modbus.Net")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("07bcb9ac-a522-4348-8774-2825fd8a6e64")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.0.1")]
|
||||
@@ -9,6 +9,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using Modbus.Net.Interface;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using Modbus.Net.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// 端格式
|
||||
@@ -43,7 +44,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 基础Api入口
|
||||
/// </summary>
|
||||
public abstract class BaseUtility<TParamIn, TParamOut, TProtocolUnit, TPipeUnit> : IUtilityProperty, IUtilityMethodData
|
||||
public abstract class BaseUtility<TParamIn, TParamOut, TProtocolUnit, TPipeUnit> : IUtility
|
||||
where TProtocolUnit : class, IProtocolFormatting<TParamIn, TParamOut> where TParamOut : class
|
||||
where TPipeUnit : PipeUnit<TParamIn, TParamOut, IProtocolLinker<TParamIn, TParamOut>, TProtocolUnit>
|
||||
{
|
||||
@@ -288,49 +289,4 @@ namespace Modbus.Net
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
public abstract void SetConnectionType(int connectionType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Api入口的抽象
|
||||
/// </summary>
|
||||
public interface IUtilityProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议是否遵循小端格式
|
||||
/// </summary>
|
||||
Endian Endian { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备是否已经连接
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识设备的连接关键字
|
||||
/// </summary>
|
||||
string ConnectionToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址翻译器
|
||||
/// </summary>
|
||||
AddressTranslator AddressTranslator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
/// <returns>设备是否连接成功</returns>
|
||||
Task<bool> ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 断开设备
|
||||
/// </summary>
|
||||
/// <returns>设备是否断开成功</returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 返回Utility的方法集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtilityMethod">Utility方法集合类型</typeparam>
|
||||
/// <returns>Utility方法集合</returns>
|
||||
TUtilityMethod GetUtilityMethods<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user