编辑 | blame | 历史 | 原始文档

S7 PLC模拟器系统设计文档

日期: 2026-03-13
作者: Claude + 用户协作
状态: 已批准


1. 需求概述

1.1 目标

创建一个基于HSL Communication库的西门子S7 PLC模拟器系统,用于WCS系统的开发测试。

1.2 核心需求

  • 支持多实例同时运行,每个实例独立配置
  • 支持多种PLC型号(S7-200 Smart, S7-1200, S7-1500等)
  • 可配置监听端口
  • Web管理界面
  • 内存数据持久化到本地文件
  • 支持M/DB/I/Q/T/C所有常用地址区域

2. 整体架构

┌──────────────────────────────────────────────────────────────────────────┐
│                     WIDESEAWCS_S7Simulator                                  │
├──────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │         Web管理界面 (Razor Pages/Blazor)                            │  │
│  │  - 服务器实例列表(卡片视图)                                         │  │
│  │  - 实例创建/编辑表单                                                  │  │
│  │  - 实例详情页(状态、内存、客户端)                                   │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                    ↕ HTTP API + SignalR                   │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │                    Web API 控制器                                    │  │
│  │  - SimulatorInstancesController (CRUD)                              │  │
│  │  - SimulatorInstanceController (启停控制)                            │  │
│  │  - MemoryController (内存读写)                                       │  │
│  │  - ClientsController (客户端管理)                                    │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                    ↕                                       │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │                      实例管理器                                      │  │
│  │  Dictionary<string, IS7ServerInstance> 管理所有实例                   │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                    ↕                                       │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │  每个实例包含: IS7ServerInstance + IMemoryStore                      │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                    ↕                                       │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │         多个HSL S7服务器实例 (不同端口)                              │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                    ↕                                       │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │              S7客户端连接 (WCS/测试工具等)                           │  │
│  └────────────────────────────────────────────────────────────────────┘  │
│                                                                            │
└──────────────────────────────────────────────────────────────────────────┘

3. 项目结构

WIDESEAWCS_S7Simulator/
├── WIDESEAWCS_S7Simulator.sln
│
├── src/
│   ├── WIDESEAWCS_S7Simulator.Core/              # 核心领域层
│   │   ├── Entities/                             # 实体
│   │   │   ├── SimulatorInstance.cs              # 实例实体
│   │   │   ├── InstanceConfig.cs                 # 实例配置
│   │   │   ├── InstanceState.cs                  # 实例状态
│   │   │   └── S7ClientConnection.cs             # 客户端连接
│   │   │
│   │   ├── Interfaces/                           # 接口
│   │   │   ├── IS7ServerInstance.cs              # 服务器实例接口
│   │   │   ├── IMemoryStore.cs                   # 内存存储接口
│   │   │   ├── IPersistenceService.cs            # 持久化服务接口
│   │   │   └── ISimulatorInstanceManager.cs      # 实例管理器接口
│   │   │
│   │   ├── Memory/                               # 内存模拟
│   │   │   ├── MemoryStore.cs                    # 内存存储实现
│   │   │   ├── MemoryRegion.cs                   # 内存区域基类
│   │   │   ├── MRegion.cs                        # M区实现
│   │   │   ├── DBRegion.cs                       # DB区实现
│   │   │   ├── IRegion.cs                        # I区实现
│   │   │   ├── QRegion.cs                        # Q区实现
│   │   │   ├── TRegion.cs                        # T区实现
│   │   │   └── CRegion.cs                        # C区实现
│   │   │
│   │   ├── Server/                               # S7服务器
│   │   │   └── S7ServerInstance.cs               # 服务器实例实现
│   │   │
│   │   ├── Persistence/                          # 数据持久化
│   │   │   ├── FilePersistenceService.cs         # 文件持久化实现
│   │   │   └── Models/
│   │   │       └── InstanceDataModel.cs          # 数据模型
│   │   │
│   │   ├── Manager/                              # 管理器
│   │   │   └── SimulatorInstanceManager.cs       # 实例管理器实现
│   │   │
│   │   └── Enums/                                # 枚举
│   │       ├── SiemensPLCType.cs                 # PLC型号
│   │       └── InstanceStatus.cs                 # 实例状态
│   │
│   ├── WIDESEAWCS_S7Simulator.Application/       # 应用服务层
│   │   ├── DTOs/                                 # 数据传输对象
│   │   │   ├── InstanceDTO.cs
│   │   │   ├── CreateInstanceDTO.cs
│   │   │   ├── UpdateInstanceDTO.cs
│   │   │   ├── MemoryReadDTO.cs
│   │   │   ├── MemoryWriteDTO.cs
│   │   │   └── ClientConnectionDTO.cs
│   │   │
│   │   ├── Services/                             # 应用服务
│   │   │   ├── SimulatorInstanceAppService.cs
│   │   │   ├── MemoryAppService.cs
│   │   │   └── ClientAppService.cs
│   │   │
│   │   └── Profiles/                             # AutoMapper配置
│   │       └── MappingProfile.cs
│   │
│   ├── WIDESEAWCS_S7Simulator.Server/           # Web API Host
│   │   ├── Controllers/
│   │   │   ├── SimulatorInstancesController.cs
│   │   │   ├── SimulatorInstanceController.cs
│   │   │   ├── MemoryController.cs
│   │   │   └── ClientsController.cs
│   │   │
│   │   ├── Infrastructure/
│   │   │   ├── DependencyInjection.cs
│   │   │   └── Middleware/
│   │   │       └── ExceptionMiddleware.cs
│   │   │
│   │   ├── Hubs/                                 # SignalR Hub
│   │   │   └── SimulatorHub.cs                   # 实时状态推送
│   │   │
│   │   ├── Program.cs
│   │   ├── appsettings.json
│   │   └── WIDESEAWCS_S7Simulator.Server.csproj
│   │
│   └── WIDESEAWCS_S7Simulator.Web/              # Web管理界面
│       ├── Pages/                                # Razor Pages
│       │   ├── Index.cshtml                      # 实例列表页
│       │   ├── Create.cshtml                     # 创建实例页
│       │   ├── Edit.cshtml                       # 编辑实例页
│       │   ├── Details.cshtml                    # 实例详情页
│       │   └── Shared/
│       │       ├── _Layout.cshtml
│       │       └── _Components/
│       │
│       ├── wwwroot/
│       │   ├── css/site.css
│       │   ├── js/site.js
│       │   └── lib/                              # 前端库
│       │
│       └── WIDESEAWCS_S7Simulator.Web.csproj
│
├── tests/
│   ├── WIDESEAWCS_S7Simulator.UnitTests/
│   │   ├── Memory/
│   │   │   ├── MRegionTests.cs
│   │   │   ├── DBRegionTests.cs
│   │   │   └── MemoryStoreTests.cs
│   │   ├── Server/
│   │   │   └── S7ServerInstanceTests.cs
│   │   └── Persistence/
│   │       └── FilePersistenceServiceTests.cs
│   │
│   └── WIDESEAWCS_S7Simulator.IntegrationTests/
│       ├── S7ClientConnectionTests.cs
│       └── APIEndpointTests.cs
│
└── docs/
    └── API.md

4. 核心组件设计

4.1 实例配置 (InstanceConfig)

public class InstanceConfig
{
    public string Id { get; set; }
    public string Name { get; set; }
    public SiemensPLCType PLCType { get; set; }
    public int Port { get; set; }
    public string ActivationKey { get; set; }
    public bool AutoStart { get; set; }
    public MemoryRegionConfig MemoryConfig { get; set; }
}

public class MemoryRegionConfig
{
    public int MRegionSize { get; set; } = 1024;
    public int DBBlockCount { get; set; } = 100;
    public int DBBlockSize { get; set; } = 1024;
    public int IRegionSize { get; set; } = 256;
    public int QRegionSize { get; set; } = 256;
    public int TRegionCount { get; set; } = 64;
    public int CRegionCount { get; set; } = 64;
}

4.2 实例状态 (InstanceState)

public class InstanceState
{
    public string InstanceId { get; set; }
    public InstanceStatus Status { get; set; }
    public int ClientCount { get; set; }
    public long TotalRequests { get; set; }
    public DateTime? StartTime { get; set; }
    public DateTime? LastActivityTime { get; set; }
    public List<S7ClientConnection> Clients { get; set; } = new();
}

public enum InstanceStatus
{
    Stopped = 0,
    Starting = 1,
    Running = 2,
    Stopping = 3,
    Error = 4
}

4.3 S7服务器实例接口 (IS7ServerInstance)

public interface IS7ServerInstance : IDisposable
{
    InstanceConfig Config { get; }
    InstanceState State { get; }
    IMemoryStore MemoryStore { get; }

    Task<OperateResult> StartAsync();
    Task<OperateResult> StopAsync();
    Task<OperateResult> RestartAsync();

    event EventHandler<InstanceStateEventArgs> StatusChanged;
    event EventHandler<ClientConnectionEventArgs> ClientConnected;
    event EventHandler<ClientConnectionEventArgs> ClientDisconnected;
}

5. 内存存储设计

5.1 内存存储接口 (IMemoryStore)

public interface IMemoryStore
{
    byte[] ReadBytes(string address, ushort length);
    T Read<T>(string address) where T : struct;
    void WriteBytes(string address, byte[] data);
    void Write<T>(string address, T value) where T : struct;
    IMemoryRegion GetRegion(string regionType);
    void Clear();
    Dictionary<string, byte[]> Export();
    void Import(Dictionary<string, byte[]> data);
}

5.2 内存区域接口 (IMemoryRegion)

public interface IMemoryRegion
{
    string RegionType { get; }
    int Size { get; }
    byte[] Read(ushort offset, ushort length);
    void Write(ushort offset, byte[] data);
    void Clear();
}

6. 数据持久化设计

6.1 持久化服务接口

public interface IPersistenceService
{
    Task SaveInstanceConfigAsync(InstanceConfig config);
    Task<InstanceConfig> LoadInstanceConfigAsync(string instanceId);
    Task<List<InstanceConfig>> LoadAllInstanceConfigsAsync();
    Task DeleteInstanceConfigAsync(string instanceId);
    Task SaveMemoryDataAsync(string instanceId, IMemoryStore memoryStore);
    Task LoadMemoryDataAsync(string instanceId, IMemoryStore memoryStore);
}

6.2 数据目录结构

Data/
├── instance-1/
│   ├── config.json
│   └── memory.json
├── instance-2/
│   ├── config.json
│   └── memory.json

7. 实例管理器设计

public interface ISimulatorInstanceManager
{
    IReadOnlyList<IS7ServerInstance> GetAllInstances();
    IS7ServerInstance GetInstance(string instanceId);
    Task<IS7ServerInstance> CreateInstanceAsync(CreateInstanceDTO createDto);
    Task UpdateInstanceAsync(string instanceId, UpdateInstanceDTO updateDto);
    Task DeleteInstanceAsync(string instanceId);
    Task<OperateResult> StartInstanceAsync(string instanceId);
    Task<OperateResult> StopInstanceAsync(string instanceId);
    Task<OperateResult> RestartInstanceAsync(string instanceId);
    Task StartAutoStartInstancesAsync();
    Task StopAllInstancesAsync();

    event EventHandler<InstanceStateEventArgs> InstanceStatusChanged;
}

8. Web API设计

方法 路径 描述
GET /api/instances 获取所有实例列表
POST /api/instances 创建新实例
GET /api/instances/{id} 获取指定实例详情
PUT /api/instances/{id} 更新实例配置
DELETE /api/instances/{id} 删除实例
POST /api/instances/{id}/start 启动实例
POST /api/instances/{id}/stop 停止实例
POST /api/instances/{id}/restart 重启实例
GET /api/instances/{id}/memory 读取内存数据
POST /api/instances/{id}/memory 写入内存数据
DELETE /api/instances/{id}/memory 清空内存数据
POST /api/instances/{id}/memory/save 保存内存快照
POST /api/instances/{id}/memory/load 加载内存快照
GET /api/instances/{id}/clients 获取连接的客户端列表
DELETE /api/instances/{id}/clients/{clientId} 断开指定客户端
POST /api/instances/start-all 启动所有自动启动实例
POST /api/instances/stop-all 停止所有实例

9. Web界面设计

9.1 技术栈

  • ASP.NET Core Razor Pages
  • Bootstrap 5 + Bootstrap Icons
  • Alpine.js (轻量级交互)
  • SignalR (实时状态推送)

9.2 主要页面

页面 功能
Index 实例列表卡片视图,显示所有实例状态
Create 创建新实例表单
Edit 编辑实例配置
Details 实例详情:状态信息、客户端列表、内存查看/编辑

10. 配置文件

{
  "urls": "http://*:5000",
  "S7Simulator": {
    "DataPath": "Data",
    "DefaultActivationKey": "4b86f3fc-f650-3b08-5924-b0f8278d6ed2",
    "EnableAutoLoad": true,
    "AutoStartInstances": true
  },
  "MemoryDefaults": {
    "MRegionSize": 1024,
    "DBBlockCount": 100,
    "DBBlockSize": 1024,
    "IRegionSize": 256,
    "QRegionSize": 256,
    "TRegionCount": 64,
    "CRegionCount": 64
  }
}

11. 测试策略

11.1 单元测试

  • MemoryStoreTests - 内存读写、边界检查、并发访问
  • MRegionTests - M区位操作、字节操作
  • DBRegionTests - DB块读写、多块管理
  • InstanceManagerTests - 实例创建、启动、停止、删除
  • PersistenceServiceTests - 配置保存/加载、内存快照

11.2 集成测试

  • S7ServerIntegrationTests - 真实S7客户端连接测试
  • APIIntegrationTests - Web API端到端测试
  • MultiInstanceTests - 多实例并发运行测试

12. 依赖包

包名 版本 用途
HslCommunication 12.6.3 S7协议通信
Microsoft.AspNetCore.SignalR 最新 实时状态推送
Serilog.AspNetCore 最新 日志记录
AutoMapper 最新 对象映射
xUnit 最新 单元测试

13. 总结

本设计实现了一个功能完整的S7 PLC模拟器系统:

  1. 多实例管理 - 支持创建和管理多个独立的S7服务器实例
  2. 灵活配置 - 每个实例可独立配置PLC型号、端口、内存大小等
  3. 数据持久化 - 配置和内存数据自动保存到本地文件
  4. Web管理界面 - 提供直观的Web UI进行实例管理
  5. 完整内存模拟 - 支持M/DB/I/Q/T/C所有常用区域
  6. 实时监控 - 显示连接状态、请求数、客户端信息等