| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 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) |
| | | |
| | | ```csharp |
| | | 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) |
| | | |
| | | ```csharp |
| | | 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) |
| | | |
| | | ```csharp |
| | | 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) |
| | | |
| | | ```csharp |
| | | 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) |
| | | |
| | | ```csharp |
| | | 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 æä¹
åæå¡æ¥å£ |
| | | |
| | | ```csharp |
| | | 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. å®ä¾ç®¡çå¨è®¾è®¡ |
| | | |
| | | ```csharp |
| | | 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. é
ç½®æä»¶ |
| | | |
| | | ```json |
| | | { |
| | | "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. **宿¶çæ§** - æ¾ç¤ºè¿æ¥ç¶æãè¯·æ±æ°ã客æ·ç«¯ä¿¡æ¯ç |