ModernIndustrial.Protocols.Keyence 1.0.0

dotnet add package ModernIndustrial.Protocols.Keyence --version 1.0.0
                    
NuGet\Install-Package ModernIndustrial.Protocols.Keyence -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ModernIndustrial.Protocols.Keyence" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ModernIndustrial.Protocols.Keyence" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ModernIndustrial.Protocols.Keyence" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ModernIndustrial.Protocols.Keyence --version 1.0.0
                    
#r "nuget: ModernIndustrial.Protocols.Keyence, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ModernIndustrial.Protocols.Keyence@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ModernIndustrial.Protocols.Keyence&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ModernIndustrial.Protocols.Keyence&version=1.0.0
                    
Install as a Cake Tool

ModernIndustrial.Net

基于 .NET 10 构建的现代化工业通信框架 — 零分配、AOT 兼容、高性能管道调度

.NET 10 License

功能树

graph TD
    A[ModernIndustrial.Net工业通信框架] --> B[通信协议支持]
    A --> C[PLC设备管理]
    A --> D[数据解析与序列化]
    A --> E[弹性与可靠性机制]
    A --> F[开发体验增强]
    A --> G[测试与模拟]
    B --> B1[Modbus协议]
    B --> B2[西门子S7协议]
    B --> B3[汇川Inovance协议]
    B --> B4[欧姆龙FINS协议]
    B --> B5[基恩士MC协议]
    B --> B6[三菱MC协议]
    B1 --> B1a[地址解析]
    B1 --> B1b[帧构建]
    B1 --> B1c[响应匹配]
    B1 --> B1d[Modbus TCP设备]
    B2 --> B2a[S7地址解析]
    B2 --> B2b[S7帧构建]
    B2 --> B2c[S7响应匹配]
    B2 --> B2d[S7字符串编解码]
    B3 --> B3a[Inovance地址解析]
    B3 --> B3b[Inovance帧构建]
    B3 --> B3c[Inovance响应匹配]
    B3 --> B3d[InovanceTcpDevice]
    B4 --> B4a[Omron地址解析]
    B4 --> B4b[Omron帧构建]
    B4 --> B4c[Omron响应匹配]
    B4 --> B4d[OmronFinsDevice]
    B5 --> B5a[Keyence地址解析]
    B5 --> B5b[Keyence帧构建]
    B5 --> B5c[Keyence响应匹配]
    B5 --> B5d[KeyenceMcDevice]
    B6 --> B6a[Mitsubishi地址解析]
    B6 --> B6b[Mitsubishi帧构建]
    B6 --> B6c[Mitsubishi响应匹配]
    B6 --> B6d[MitsubishiMcDevice]
    C --> C1[设备工厂]
    C --> C2[连接配置]
    C --> C3[健康检查]
    C --> C4[连接池管理]
    D --> D1[端序解析]
    D --> D2[批量类型转换]
    D --> D3[PLC字符串解码]
    D1 --> D1a[ABCD模式]
    D1 --> D1b[DCBA模式]
    D1 --> D1c[BADC模式]
    D1 --> D1d[CDAB模式]
    E --> E1[连接状态机]
    E --> E2[指数退避重连]
    E --> E3[挂起队列缓冲]
    E --> E4[防击穿缓存]
    F --> F1[源生成实体映射]
    F --> F2[依赖注入扩展]
    G --> G1[虚拟Modbus服务器]
    G --> G2[核心功能单元测试]

设计哲学

ModernIndustrial.Net 是对 HslCommunication 等传统工控通信库的 现代化重构。它利用 .NET 10 的全新技术栈,在极端 AOT 亲和性、零 GC 抖动、极高吞吐量三个维度实现全面超越。

核心技术栈

传统技术 现代 .NET 10 替代 收益
NetworkStream.Read/Write + new byte[] System.IO.Pipelines + MemoryPool<byte> 零分配高吞吐数据流
lock(obj) 阻塞排队 System.Threading.Channels 无锁调度 + 背压控制
BitConverter + Array.Reverse BinaryPrimitives + Unsafe.BitCast SIMD 向量化端序解析
ReadInt16 / ReadFloat 方法爆炸 INumber<T> 泛型数学 单一泛型方法覆盖所有值类型
string.Split / Regex 地址解析 ReadOnlySpan<char> + ISpanParsable<T> 地址解析零堆分配
System.Reflection 实体映射 Roslyn Source Generators 编译期生成,100% AOT
Thread/Timer + event 轮询 IAsyncEnumerable<T> + PeriodicTimer 不占线程、无内存泄漏
手动加锁缓存 HybridCache API 级防击穿保护

解决方案结构

ModernIndustrial.sln
│
├── src/
│   ├── ModernIndustrial.Abstractions          ← 零依赖契约层
│   ├── ModernIndustrial.Core                  ← 管道调度 / 端序解析 / 弹性重连
│   ├── ModernIndustrial.Protocols.Modbus      ← Modbus TCP/RTU
│   ├── ModernIndustrial.Protocols.Siemens     ← 西门子 S7
│   ├── ModernIndustrial.Protocols.Inovance    ← 汇川 AM400/AM400_800
│   ├── ModernIndustrial.Protocols.Omron       ← 欧姆龙 FINS TCP
│   ├── ModernIndustrial.Protocols.Keyence     ← 基恩士 MC Protocol
│   ├── ModernIndustrial.Protocols.Mitsubishi  ← 三菱 MC Protocol
│   ├── ModernIndustrial.Extensions.Hosting    ← DI / 连接池 / HybridCache
│   └── ModernIndustrial.Generators            ← Roslyn 源生成器 (AOT 实体映射)
│
└── tests/
    ├── ModernIndustrial.Tests                 ← 单元 + 集成测试
    └── ModernIndustrial.Simulator             ← 内存 PLC 模拟器

支持的 PLC 协议

品牌 系列 协议 默认端口 支持的存储区域
西门子 S7-200/300/400/1200/1500 S7comm 102 DB/M/I/Q/T/C
Modbus 标准 Modbus TCP Modbus TCP 502 0x/4x 寄存器
汇川 AM400/AM400_800 专有 TCP 501 D/M/X/Y/S/T/C/R/V
汇川 H3U/H5U/Easy/XP Modbus TCP 502 同 Modbus
欧姆龙 CJ/CS/CP/CV/NX/NJ FINS TCP 9600 CIO/W/H/A/D/EM/T/C
基恩士 KV-8000/7000/5000/3000/1000 MC Protocol 8501 MR/CR/HR/AR/LR/DM/EM/TM/CM
三菱 Q/L/iQ-R/iQ-F/FX MC Protocol 5007 X/Y/M/D/L/R/Z/TN/CN

快速开始

1. 注册服务

// Program.cs 或 MauiProgram.cs
services.AddModernIndustrial(builder =>
{
    // 西门子 S7-1200/1500
    builder.AddS7("Line1_Siemens", "192.168.1.100", rack: 0, slot: 1, options =>
    {
        options.FloatOrder = FloatByteOrder.BADC; // 西门子浮点端序 (字交换)
    });

    // Modbus TCP 设备
    builder.AddModbusTcp("Inverter1", "192.168.1.200", port: 502, options =>
    {
        options.RequestTimeout = TimeSpan.FromSeconds(5);
    });

    // 汇川 AM400/AM400_800
    builder.AddInovance("InovancePLC", "192.168.1.150", port: 501);

    // 欧姆龙 CJ/NJ/NX 系列
    builder.AddOmron("OmronPLC", "192.168.1.160", port: 9600);

    // 基恩士 KV-8000/7000
    builder.AddKeyence("KeyencePLC", "192.168.1.170", port: 8501);

    // 三菱 Q/L/iQ-F/FX 系列
    builder.AddMitsubishi("MitsubishiPLC", "192.168.1.180", port: 5007);
});

2. 单值读取

public class ProductionMonitor(IPlcDeviceManager manager)
{
    private readonly IPlcDevice _plc = manager.GetDevice("Line1_Siemens");

    public async Task<float> GetTemperatureAsync()
    {
        var result = await _plc.ReadAsync<float>("DB1.DBD10");
        return result.IsSuccess ? result.Value : throw new Exception(result.Error.Message);
    }
}

3. 持续订阅流(替代 Timer + Event)

public async Task StartMonitoringAsync(CancellationToken ct)
{
    // 每 200ms 轮询一次,数据以异步流形式推送
    await foreach (var data in _plc.PollAsync<float>("DB1.DBD10", TimeSpan.FromMilliseconds(200), ct))
    {
        if (data.IsSuccess)
        {
            CurrentTemperature = data.Value;
            NotifyStateChanged();
        }
    }
}

4. HybridCache 防击穿保护

public class ProductionDataService(IPlcDeviceManager manager, HybridCache cache)
{
    public async ValueTask<short> GetMachineStatusAsync(CancellationToken ct)
    {
        return await cache.GetOrCreateAsync(
            "Machine1_Status",
            async (cancel) =>
            {
                var result = await _manager.GetDevice("Line1_Siemens")
                    .ReadAsync<short>("DB1.DBW20", cancel);
                return result.IsSuccess ? result.Value : throw new Exception();
            },
            cancellationToken: ct
        );
    }
}

5. 编译期实体映射(零反射,100% AOT)

// 1. 定义实体类(partial class + Attribute)
[PlcEntity]
public partial class ProcessRecipe
{
    [PlcAddress("DB1.DBD0")] public float Temperature { get; set; }
    [PlcAddress("DB1.DBD4")] public float Pressure { get; set; }
    [PlcAddress("DB1.DBW8")] public short Status { get; set; }
}

// 2. 编译期自动生成的代码(用户不可见)
//    ProcessRecipeMapper.ParseFromSpan(span, reader)
//    ProcessRecipeMapper.WriteToSpan(recipe, span, reader)

// 3. 业务层调用
byte[] buffer = new byte[ProcessRecipeMapper.GetTotalByteLength()];
await _plc.ReadRawAsync("DB1.DBD0", buffer.Length, buffer);
var recipe = ProcessRecipeMapper.ParseFromSpan(buffer, _endianReader);

各品牌 PLC 使用示例

汇川 (Inovance) AM400/AM400_800

// 注册
builder.AddInovance("AM400", "192.168.1.150", port: 501);

// 读取 D 寄存器(数据寄存器)
var device = manager.GetDevice("AM400");
var dValue = await device.ReadAsync<short>("D100");

// 读取 M 继电器(位)
var mValue = await device.ReadAsync<byte>("M200");
bool isOn = mValue.IsSuccess && mValue.Value != 0;

// 批量读取 D 寄存器数组
byte[] buffer = new byte[20]; // 10个寄存器
await device.ReadBlockAsync("D100", buffer);

// 或使用类型安全的便捷方法(如果直接持有 InovanceTcpDevice)
if (device is InovanceTcpDevice inovance)
{
    short dReg = await inovance.ReadDAsync(100);
    bool mRelay = await inovance.ReadMAsync(200);
    short[] dArray = await inovance.ReadDArrayAsync(100, 10);
}

支持的存储区域:

  • D - 数据寄存器(Word 读写,最常用)
  • M - 辅助继电器(Bit 读写)
  • X/Y - 输入/输出(Bit 读/写)
  • S - 状态继电器(Bit 读写)
  • T/C - 定时器/计数器(Word 读/写)
  • R - 闪存寄存器(Word 读写,断电保持)
  • V - 变量寄存器(Word 读写)

欧姆龙 (Omron) FINS TCP

// 注册
builder.AddOmron("OmronCJ", "192.168.1.160", port: 9600);

// 读取 DM 区域(数据存储器)
var device = manager.GetDevice("OmronCJ");
var dmValue = await device.ReadAsync<short>("DM100");

// 读取 CIO 区域(位)
var cioValue = await device.ReadAsync<byte>("CIO100.05"); // 位地址

// 读取工作继电器
var wrValue = await device.ReadAsync<byte>("W200.03");

// 批量读取
byte[] buffer = new byte[20];
await device.ReadBlockAsync("DM100", buffer);

支持的存储区域:

  • D - DM 数据存储器(Word 读写)
  • CIO - CIO 区域(Bit 读写)
  • W/H/A - 工作/保持/辅助继电器(Bit 读写)
  • EM - 扩展存储器(Word 读写)
  • T/C - 定时器/计数器(Word 读)

基恩士 (Keyence) MC Protocol

// 注册
builder.AddKeyence("KeyenceKV", "192.168.1.170", port: 8501);

// 读取 DM 寄存器
var device = manager.GetDevice("KeyenceKV");
var dmValue = await device.ReadAsync<short>("DM100");

// 读取 MR 继电器(位)
var mrValue = await device.ReadAsync<byte>("MR200.05");

// 批量读取
byte[] buffer = new byte[20];
await device.ReadBlockAsync("DM100", buffer);

支持的存储区域:

  • DM - 数据存储器(Word 读写)
  • MR/CR/HR/AR/LR - 各类继电器(Bit 读写)
  • EM - 扩展存储器(Word 读写)
  • WDM - 文件寄存器(Word 读写)
  • TM/CM - 定时器/计数器(Word 读)

三菱 (Mitsubishi) MC Protocol

// 注册
builder.AddMitsubishi("MitsubishiQ", "192.168.1.180", port: 5007);

// 读取 D 寄存器
var device = manager.GetDevice("MitsubishiQ");
var dValue = await device.ReadAsync<short>("D100");

// 读取 X 输入(位)
var xValue = await device.ReadAsync<byte>("X0");

// 读取 Y 输出(位)
var yValue = await device.ReadAsync<byte>("Y10");

// 读取 M 继电器
var mValue = await device.ReadAsync<byte>("M200");

// 批量读取
byte[] buffer = new byte[20];
await device.ReadBlockAsync("D100", buffer);

支持的存储区域:

  • D - 数据寄存器(Word 读写,最常用)
  • X/Y - 输入/输出(Bit 读/写)
  • M - 内部继电器(Bit 读写)
  • L - 锁存继电器(Bit 读写)
  • R - 文件寄存器(Word 读写)
  • Z - 变址寄存器(Word 读写)
  • TN/CN - 定时器/计数器当前值(Word 读)
  • TC/CC - 定时器/计数器触点(Bit 读)

高级特性

浮点数端序支持

工业设备的浮点存储有四种标准模式,框架在连接级别支持配置:

模式 字节序 常见设备
ABCD Big-Endian Modicon / 施耐德
DCBA Little-Endian 部分国产 PLC
BADC 字交换 (Mid-Big) 西门子 S7
CDAB 字交换 (Mid-Little) AB / 罗克韦尔

自动断线重连

设备内部维护状态机(Disconnected → Connecting → Connected → Faulted → Reconnecting),使用指数退避算法自动重连。连接断开时,业务层的请求会在 BoundedChannel 中安全挂起,重连成功后自动恢复流转。

背压控制

发送队列采用 BoundedChannel(默认 256 深度),当请求堆积达到上限时,新请求会被挂起等待而非无限堆积,从根源上保护 PLC 设备不被冲垮。

API 参考

IPlcDevice 核心接口

方法 签名 说明
ReadAsync<T> ValueTask<PlcResult<T>> ReadAsync<T>(string address, CancellationToken ct = default) 单值泛型读取,T: unmanaged, INumber<T>
WriteAsync<T> ValueTask<PlcResult> WriteAsync<T>(string address, T value, CancellationToken ct = default) 单值泛型写入
ReadBlockAsync ValueTask<PlcResult<int>> ReadBlockAsync(string startAddress, Memory<byte> buffer, CancellationToken ct = default) 批量块读取(零拷贝)
WriteBlockAsync ValueTask<PlcResult> WriteBlockAsync(string startAddress, ReadOnlyMemory<byte> data, CancellationToken ct = default) 批量块写入
ReadRawAsync ValueTask<PlcResult<int>> ReadRawAsync(string address, int byteLength, Memory<byte> buffer, CancellationToken ct = default) 原始字节读取(供 Source Generator 调用)
ReadStringAsync ValueTask<PlcStringResult> ReadStringAsync(string address, int maxLength, CancellationToken ct = default) 字符串读取
PollAsync<T> IAsyncEnumerable<PlcResult<T>> PollAsync<T>(string address, TimeSpan interval, CancellationToken ct = default) 持续订阅流

PlcResult<T> 结果结构

public readonly record struct PlcResult<T> where T : unmanaged
{
    public T Value { get; init; }
    public PlcError Error { get; init; }
    public bool IsSuccess => Error.Code == 0;

    public static implicit operator PlcResult<T>(T value);
    public static implicit operator PlcResult<T>(PlcError error);
}

测试

# 运行全部测试
dotnet test tests/ModernIndustrial.Tests --verbosity normal

# 仅运行集成测试
dotnet test tests/ModernIndustrial.Tests --filter "ModbusTcpIntegrationTests"

测试包含一个内存 Modbus TCP 模拟器,无需物理 PLC 即可运行端到端集成测试。

编译要求

  • .NET SDK 10.0+
  • 支持的操作系统:Windows / Linux / macOS
  • 支持 Native AOT 发布
# 编译全部项目
dotnet build ModernIndustrial.sln

# Native AOT 发布(需具体目标运行时)
dotnet publish -c Release -r linux-x64 --aot

许可证

MIT License

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ModernIndustrial.Protocols.Keyence:

Package Downloads
ModernIndustrial.Extensions.Hosting

DI extensions, connection pooling, and HybridCache integration for ModernIndustrial.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 192 4/17/2026 1.0.0 is deprecated because it is no longer maintained and has critical bugs.