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

S7 模拟器数据库实例同步设计

背景

S7 模拟器当前通过本地 JSON 文件手动配置实例和协议模板,工作量大且容易出错。WCS 系统已有完整的设备信息数据库(SQL Server),包含 Dt_DeviceInfoDt_DeviceProtocol 表。需要实现从数据库自动同步设备到 S7 模拟器实例。

需求

  1. 数据源Dt_DeviceInfo.DevicePlcType = 'SiemensS7'
  2. 协议模板:每个设备生成一个协议模板,包含该设备所有 Dt_DeviceProtocol 字段
  3. 内存配置:统一使用默认值(M区1024字节,DB块1个,DB块大小65536)
  4. 同步时机:启动时自动同步 + API 手动触发

整体架构

启动时 / API触发
       │
       ▼
┌─────────────────────────────┐
│  InstanceSyncService        │
│  (Application 层)           │
└─────────────┬───────────────┘
              │ 读取 Dt_DeviceInfo (DevicePlcType='SiemensS7')
              │ 读取 Dt_DeviceProtocol (按 DeviceId 关联)
              ▼
┌─────────────────────────────┐
│  DatabaseDeviceService      │
│  (Application 层)           │
│  - SqlSugar 连接 WCS DB      │
└─────────────┬───────────────┘
              │ InstanceConfig + ProtocolTemplate
              ▼
┌─────────────────────────────┐
│  SimulatorInstanceManager   │
│  - 创建/更新实例             │
│  - 应用内存默认值            │
└─────────────────────────────┘

新增组件

组件 位置 职责
WcsDbOptions Application 数据库连接配置类
DatabaseDeviceService Application 读取 WCS 设备数据
InstanceSyncService Application 同步逻辑
SyncController Server API 接口

配置新增

appsettings.json 添加:

{
  "WcsDb": {
    "Enabled": true,
    "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=${WCS_DB_PASSWORD};...",
    "DbType": 2
  }
}

Note: DbType uses integer values (SqlServer=2, MySql=1). ${WCS_DB_PASSWORD} is an environment variable placeholder.

协议模板映射

Dt_DeviceProtocol 字段 ProtocolTemplate 字段
DeviceChildCode fieldKey
DeviceProDataBlock dbNumber
DeviceProOffset offset
DeviceProDataType dataType(需转换映射)
DeviceProDataLength length
固定值 1 bit
Bidirectional (2) direction

数据类型映射

ProtocolDataType 枚举值:Byte=0, Int=1, DInt=2, String=3, Bool=4

数据库 DeviceProDataType ProtocolDataType
Bit Bool (4)
Byte Byte (0)
Int, Word Int (1)
DInt DInt (2)
String, String8, String16 String (3)

实例配置默认值

new MemoryRegionConfig
{
    MRegionSize = 1024,
    DBBlockCount = 1,
    DBBlockNumbers = new List<int> { 50 },
    DBBlockSize = 65536,
    IRegionSize = 256,
    QRegionSize = 256,
    TRegionCount = 64,
    CRegionCount = 64
}

协议模板 ID 格式

protocol-{DeviceCode}

每个设备(DeviceCode)生成一个协议模板,包含该设备所有 DeviceChildCode 的协议字段。

API 接口

方法 路径 说明
POST /api/Sync/SyncInstances 手动触发同步
GET /api/Sync/LastSyncTime 获取上次同步时间

同步逻辑

  1. 读取数据库中所有 DevicePlcType = 'SiemensS7' 的设备
  2. 对每个设备,创建 InstanceConfig(ID = DeviceCode,端口 = DevicePort)
  3. 对每个设备,合并其所有 Dt_DeviceProtocol 记录生成协议模板
  4. 对比现有实例:
  • 新增的:创建实例 + 保存协议模板
  • 已存在的:更新实例配置(可选)
  • 数据库已删除的:从内存移除,保留文件配置
  1. 同步后实例状态默认为 Stopped(不自动启动)

文件变更

新增文件

  • WIDESEAWCS_S7Simulator.Application/WcsDbOptions.cs
  • WIDESEAWCS_S7Simulator.Application/DatabaseDeviceService.cs
  • WIDESEAWCS_S7Simulator.Application/InstanceSyncService.cs
  • WIDESEAWCS_S7Simulator.Server/Controllers/SyncController.cs

修改文件

  • WIDESEAWCS_S7Simulator.Server/appsettings.json - 添加 WcsDb 配置
  • WIDESEAWCS_S7Simulator.Server/Program.cs - 注册服务、启动时同步