feat: 空托盘出库完整流程 + 输送线调度优化 + S7Simulator 协议同步增强
feat: 空托盘出库完整流程 + 输送线调度优化 + S7Simulator 协议同步增强
【WCS - 空托盘出库完整流程】
- ConfigKey: 新增 OutboundFinishTaskTray 枚举,表示通知 WMS 空托盘出库完成
- ApiRouteCacheWarmupHostedService: 注册 OutboundFinishTaskTray API 路由
- OutboundTaskFlowService:
- 空托盘出库完成时调用 WMS 的 OutboundFinishTaskTray 接口通知完成
- 增加 GetWMSRobotTask 调用失败的错误处理
- RobotTaskService: 修正 RobotSourceAddress/TargetAddress 使用 taskDTO 的
SourceAddress/TargetAddress,替代之前的 lineNo
【WCS - 输送线调度优化】
- CommonConveyorLineNewJob:
- 禁用 Parallel.For 并行处理,改为串行 foreach,避免并发问题
- JsonSerializer 替换为 JsonConvert.DeserializeObject
- CV_State 判断从 .ObjToBool() 改为 == 1
- existingTask 查询改用 Db.Queryable 方式
- 修复 WMS 任务反序列化:WMSTaskDTO 替代 List<WMSTaskDTO>
- ConveyorLineDispatchHandler:
- 出库完成时将 WCS_ACK 确认移至 UpdateTaskStatusToNext 之后,
确保状态更新成功后再回复 PLC
【WMS - 空托盘出库完成接口 + 机械手任务地址规则】
- ILocationInfoService / LocationInfoService: 新增 GetLocationInfoAsync(int id)
- ITaskService: 新增 OutboundFinishTaskTrayAsync 接口声明
- TaskService_WCS:
- GetOutBoundTrayTaskAsync: 新增任务存在性检查(TargetAddress 查重),
有任务时直接返回;创建任务时增加货位锁定和事务包装
- CreateRobotTaskAsync: 从配置 RobotTaskAddressRules 读取源/目标地址,
而非直接使用 lineNo
- TaskController: 注册 OutboundFinishTaskTrayAsync 接口;
修正 CreateTaskInboundTrayAsync 方法注释(入库而非出库)
- appsettings.json:
- 修正 AGV 配置键名(AGV_OutTaskComplete → A0GV_OutTaskComplete)
- 新增 RobotTaskAddressRules 配置节
【S7Simulator - 协议同步增强】
- InstanceSyncService:
- 预计算 DB 编号缓存字典,避免在每个 FieldKey 中重复解析
- MemoryConfig.DBBlockNumbers 改为根据实际使用的 DB 编号动态生成
- 删除已废弃实例的 memory.json(instance-CWSC1/GWSC1/HCSC1/Line1/Line2)
- 新增实例目录:instance-1001、instance-1002、instance-1003、instance-PM
- protocol-templates.json: fieldKey 加上 DeviceChildCode 前缀(与 fieldKey
前缀变更一致,1600+ 行更新)
fix: 协议模板fieldKey加上DeviceChildCode前缀
例如 11001_Target
fix: 修复数据库同步问题 - DbType.SqlServer 和 SugarTable 属性
- DatabaseDeviceService 使用 DbType.SqlServer 显式设置
- DTO 添加 [SugarTable] 属性指定真实表名
- appsettings.json 添加 WcsDb 配置
fix: 将 Initial Catalog 改为 Database 尝试解决 SqlSugar 连接问题
chore: 构建验证通过
feat: Program.cs 注册同步服务并启动时同步
feat: 添加 SyncController API 接口
feat: 添加 InstanceSyncService 同步协调逻辑
feat: 添加 DatabaseDeviceService 读取 WCS 数据库
feat: 添加 WcsDbOptions 配置类
feat: 添加 WCS 设备 DTO
feat: 添加 SqlSugarCore 依赖用于数据库连接
fix: 整合启动同步逻辑,使用环境变量占位符
- 将WCS数据库同步整合到现有的启动Task.Run中
- 连接串密码使用${WCS_DB_PASSWORD}占位符
- 修正spec中DbType为整数类型
fix: 修正协议模板ID格式和数据类型映射
- 协议模板ID改为 protocol-{DeviceCode}(每个设备一个模板)
- 更新数据类型映射表以匹配 ProtocolDataType 枚举实际值
- Direction 改为 Bidirectional (2)
docs: 添加数据库实例同步实现计划
docs: 添加数据库实例同步设计文档
已添加10个文件
已重命名1个文件
已删除5个文件
已修改19个文件
| | |
| | | /// </summary> |
| | | CreateRobotSplitPalletTask, |
| | | |
| | | /// <summary> |
| | | /// 空æçåºåºå®æï¼æ ¹æ®ä»»å¡å·åæçå·éç¥WMS空æçåºåºå®æï¼ |
| | | /// </summary> |
| | | OutboundFinishTaskTray |
| | | |
| | | #endregion WMSæ¥å£ |
| | | } |
| | | } |
| | |
| | | (nameof(ConfigKey.RelocationFinishTask), "Task/RelocationFinishTask"), |
| | | (nameof(ConfigKey.CreateRobotGroupPalletTask), "Task/CreateRobotGroupPalletTask"), |
| | | (nameof(ConfigKey.CreateRobotChangePalletTask), "Task/CreateRobotChangePalletTask"), |
| | | (nameof(ConfigKey.CreateRobotSplitPalletTask), "Task/CreateRobotSplitPalletTask") |
| | | (nameof(ConfigKey.CreateRobotSplitPalletTask), "Task/CreateRobotSplitPalletTask"), |
| | | (nameof(ConfigKey.OutboundFinishTaskTray), "Task/OutboundFinishTaskTray") |
| | | }; |
| | | |
| | | private readonly ICacheService _cache; |
| | |
| | | |
| | | if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty) |
| | | { |
| | | return _robotTaskService.GetWMSRobotTask(task); |
| | | WebResponseContent content = _robotTaskService.GetWMSRobotTask(task); |
| | | if (!content.Status) |
| | | { |
| | | return content; |
| | | } |
| | | return OutboundFinishTaskTray(task); |
| | | } |
| | | |
| | | if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutExecuting) |
| | |
| | | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 空æçåºåºå®æåæ¥å°WMSã |
| | | /// </summary> |
| | | /// <param name="task">ä»»å¡å®ä½ã</param> |
| | | /// <returns>åæ¥ç»æã</returns> |
| | | private WebResponseContent OutboundFinishTaskTray(Dt_Task task) |
| | | { |
| | | var result = _httpClientHelper.Post<WebResponseContent>( |
| | | nameof(ConfigKey.OutboundFinishTaskTray), |
| | | new CreateTaskDto { PalletCode = task.PalletCode, SourceAddress = task.SourceAddress }.ToJson()); |
| | | |
| | | if (!result.IsSuccess || !result.Data.Status) |
| | | return WebResponseContent.Instance.Error($"è°ç¨WMSæ¥å£æ´æ°ä»»å¡ç¶æå¤±è´¥,ä»»å¡å·:ã{task.TaskNum}ã,é误信æ¯:ã{result.Data?.Message}ã"); |
| | | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | } |
| | | } |
| | |
| | | RobotSourceAddressLineCode = stockDTO.SourceLineNo, |
| | | RobotTargetAddressLineCode = stockDTO.TargetLineNo, |
| | | RobotRoadway = stockDTO.Roadway, |
| | | RobotSourceAddress = stockDTO.SourceLineNo, |
| | | RobotTargetAddress = stockDTO.TargetLineNo, |
| | | RobotSourceAddress = taskDTO.SourceAddress, |
| | | RobotTargetAddress = taskDTO.TargetAddress, |
| | | RobotSourceAddressPalletCode = stockDTO.SourcePalletNo, |
| | | RobotTargetAddressPalletCode = stockDTO.TargetPalletNo, |
| | | RobotTaskType = taskDTO.TaskType, |
| | |
| | | using MapsterMapper; |
| | | using Microsoft.Extensions.Configuration; |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using Quartz; |
| | | using SqlSugar; |
| | | using System.Text.Json; |
| | |
| | | } |
| | | |
| | | // å建并è¡é项ï¼é嶿大并忰 |
| | | var parallelOptions = new ParallelOptions |
| | | { |
| | | // éå¶å¹¶åæ°ï¼åè®¾å¤æ°éå CPU æ ¸å¿æ°*2 çè¾å°å¼ |
| | | MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2), |
| | | }; |
| | | //var parallelOptions = new ParallelOptions |
| | | //{ |
| | | // // éå¶å¹¶åæ°ï¼åè®¾å¤æ°éå CPU æ ¸å¿æ°*2 çè¾å°å¼ |
| | | // MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2), |
| | | //}; |
| | | |
| | | _logger.LogDebug("Executeï¼å¼å§å¹¶è¡å¤çè¾é线 {DeviceCode}ï¼åè®¾å¤æ°é: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count); |
| | | QuartzLogger.Debug($"å¼å§å¹¶è¡å¤çè¾é线ï¼åè®¾å¤æ°é: {childDeviceCodes.Count}", conveyorLine.DeviceCode); |
| | | |
| | | // å¹¶è¡å¤çæ¯ä¸ªåè®¾å¤ |
| | | Parallel.For(0, childDeviceCodes.Count, parallelOptions, i => |
| | | //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i => |
| | | foreach (var childDeviceCode in childDeviceCodes) |
| | | { |
| | | string childDeviceCode = childDeviceCodes[i]; |
| | | //string childDeviceCode = childDeviceCodes[i]; |
| | | var correlationId = Guid.NewGuid().ToString("N"); |
| | | try |
| | | { |
| | |
| | | { |
| | | _logger.LogDebug("Executeï¼åè®¾å¤ {ChildDeviceCode} å½ä»¤ä¸ºç©ºï¼è·³è¿", childDeviceCode); |
| | | QuartzLogger.Debug($"åè®¾å¤ {childDeviceCode} å½ä»¤ä¸ºç©ºï¼è·³è¿", conveyorLine.DeviceCode); |
| | | return; |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | // 妿 WCS_ACK 为 1ï¼å
æ¸
é¤ï¼è¡¨ç¤ºå¤çè¿ä¸ä¸æ¬¡è¯·æ±ï¼ |
| | |
| | | if (checkPalletPositions.Any(x => x.Code == childDeviceCode)) |
| | | { |
| | | // æ£æ¥è¾éçº¿ç¶æï¼æ¯å¦ææçï¼ |
| | | if (command.CV_State.ObjToBool()) |
| | | if (command.CV_State == 1) |
| | | { |
| | | // æ£æ¥è¯¥ä½ç½®æ¯å¦å·²æä»»å¡ |
| | | var existingTask = _taskService.Repository.QueryFirst(x => x.TargetAddress == childDeviceCode); |
| | | var existingTask = _taskService.Db.Queryable<Dt_Task>().First(x => x.TargetAddress == childDeviceCode); |
| | | if (existingTask.IsNullOrEmpty()) |
| | | { |
| | | // 没æä»»å¡ï¼å WMS 请æ±åºåºæçä»»å¡ |
| | |
| | | // å¦æè¯·æ±æåï¼æ¥æ¶ WMS è¿åçä»»å¡ |
| | | if (responseResult.IsSuccess && responseResult.Data.Status) |
| | | { |
| | | var wmsTask = JsonSerializer.Deserialize<List<WMSTaskDTO>>(responseResult.Data.Data.Serialize()); |
| | | var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult.Data.Data.ToString()); |
| | | List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask }; |
| | | if (wmsTask != null) |
| | | _taskService.ReceiveWMSTask(wmsTask); |
| | | _taskService.ReceiveWMSTask(taskDTOs); |
| | | } |
| | | } |
| | | } |
| | |
| | | // åªæå½ PLC_STB 为 1 æ¶æå¤çä»»å¡ |
| | | if (command.PLC_STB != 1) |
| | | { |
| | | _logger.LogDebug("Executeï¼åè®¾å¤ {ChildDeviceCode} PLC_STB ä¸ä¸º1ï¼è·³è¿", childDeviceCode); |
| | | QuartzLogger.Debug($"åè®¾å¤ {childDeviceCode} PLC_STB ä¸ä¸º1ï¼è·³è¿", conveyorLine.DeviceCode); |
| | | return; |
| | | //_logger.LogDebug("Executeï¼åè®¾å¤ {ChildDeviceCode} PLC_STB ä¸ä¸º1ï¼è·³è¿", childDeviceCode); |
| | | //QuartzLogger.Debug($"åè®¾å¤ {childDeviceCode} PLC_STB ä¸ä¸º1ï¼è·³è¿", conveyorLine.DeviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | // ========== å¤çæ æçæ¡ç çæ
åµ ========== |
| | |
| | | _logger.LogDebug("Executeï¼åè®¾å¤ {ChildDeviceCode} æ æçæ¡ç ï¼è¯·æ±åºåºä»»å¡", childDeviceCode); |
| | | QuartzLogger.Debug($"åè®¾å¤ {childDeviceCode} æ æçæ¡ç ï¼è¯·æ±åºåºä»»å¡", conveyorLine.DeviceCode); |
| | | _conveyorLineDispatch.RequestOutbound(conveyorLine, command, childDeviceCode); |
| | | return; |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | // ========== å¤çå·²æä»»å¡å·çæ
åµ ========== |
| | |
| | | QuartzLogger.Info($"å¤çä»»å¡ {task.TaskNum}ï¼ç¶æ: {task.TaskStatus}", conveyorLine.DeviceCode); |
| | | // å¤çä»»å¡ç¶æï¼æ ¹æ®ç¶æååå°ä¸åæ¹æ³ï¼ |
| | | ProcessTaskState(conveyorLine, command, task, childDeviceCode); |
| | | return; |
| | | return Task.CompletedTask; |
| | | } |
| | | } |
| | | } |
| | |
| | | _logger.LogError(innerEx, "Executeï¼åè®¾å¤ {ChildDeviceCode} å¤çå¼å¸¸ï¼CorrelationId: {CorrelationId}", childDeviceCode, correlationId); |
| | | QuartzLogger.Error($"å设å¤å¤çå¼å¸¸: {innerEx.Message}", conveyorLine.DeviceCode, innerEx); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode); |
| | | if (task != null) |
| | | { |
| | | // åå¤ ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | |
| | | // æ´æ°ä»»å¡ç¶æå°ä¸ä¸é¶æ®µï¼é常æ¯å®æï¼ |
| | | WebResponseContent content = _taskService.UpdateTaskStatusToNext(task); |
| | | |
| | | // åå¤ ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | |
| | | _logger.LogInformation("ConveyorLineOutFinishï¼åºåºå®æï¼ä»»å¡å·: {TaskNum}ï¼å设å¤: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"åºåºå®æï¼ä»»å¡å·: {task.TaskNum}", conveyorLine.DeviceCode); |
| | | } |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è´§ä½IDè·åè´§ä½ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="id">è´§ä½id</param> |
| | | /// <returns>è´§ä½ä¿¡æ¯</returns> |
| | | public async Task<Dt_LocationInfo> GetLocationInfoAsync(int id) |
| | | { |
| | | return await BaseDal.QueryFirstAsync(x => x.Id == id); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ´æ°è´§ä½ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="locationInfo">è´§ä½ä¿¡æ¯å¯¹è±¡</param> |
| | |
| | | /// <param name="taskNum">ä»»å¡å·</param> |
| | | /// <returns>ä»»å¡ä¿¡æ¯</returns> |
| | | Task<WebResponseContent> TransferCheckAsync(int taskNum); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è´§ä½IDè·åè´§ä½ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="id">è´§ä½id</param> |
| | | /// <returns>è´§ä½ä¿¡æ¯</returns> |
| | | Task<Dt_LocationInfo> GetLocationInfoAsync(int id); |
| | | } |
| | | } |
| | |
| | | Task<WebResponseContent> GetOutBoundTrayTaskAsync(CreateTaskDto taskDto); |
| | | |
| | | /// <summary> |
| | | /// 空æçåºåºå®æ |
| | | /// </summary> |
| | | Task<WebResponseContent> OutboundFinishTaskTrayAsync(CreateTaskDto taskDto); |
| | | |
| | | /// <summary> |
| | | /// ä¿®æ¹ä»»å¡ç¶æï¼æ ¹æ®ä»»å¡IDä¿®æ¹ä¸ºæå®ç¶æï¼ |
| | | /// </summary> |
| | | /// <param name="taskId"></param> |
| | |
| | | { |
| | | try |
| | | { |
| | | var dt_Task = await BaseDal.QueryFirstAsync(x => x.TargetAddress == taskDto.TargetAddress); |
| | | if (!dt_Task.IsNullOrEmpty()) |
| | | { |
| | | var taskDTO = dt_Task.Adapt<WMSTaskDTO>(); |
| | | return WebResponseContent.Instance.OK("ä»»å¡å建æå", taskDTO); |
| | | } |
| | | |
| | | var stockInfo = await _stockInfoService.Repository.QueryDataNavFirstAsync(x => x.LocationDetails.WarehouseId == taskDto.WarehouseId && x.LocationDetails.LocationStatus == LocationStatusEnum.InStock.GetHashCode() && x.StockStatus == StockStatusEmun.空æçåºå.GetHashCode()); |
| | | if (stockInfo == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçåºåä¿¡æ¯"); |
| | |
| | | TaskNum = await BaseDal.GetTaskNo(), |
| | | Creater = "system", |
| | | }; |
| | | var taskDtos = task.Adapt<WMSTaskDTO>(); |
| | | |
| | | var addResult = await BaseDal.AddDataAsync(task) > 0; |
| | | if (!addResult) |
| | | return WebResponseContent.Instance.Error("ä»»å¡å建失败"); |
| | | return WebResponseContent.Instance.OK("ä»»å¡å建æå", taskDtos); |
| | | return await ExecuteWithinTransactionAsync(async () => |
| | | { |
| | | var locationInfo = await _locationInfoService.GetLocationInfoAsync(stockInfo.LocationId); |
| | | locationInfo.LocationStatus = LocationStatusEnum.InStockLock.GetHashCode(); |
| | | var updateLocationResult = await _locationInfoService.UpdateLocationInfoAsync(locationInfo); |
| | | if (!updateLocationResult) |
| | | return WebResponseContent.Instance.Error("ä»»å¡å建失败"); |
| | | |
| | | var taskDtos = task.Adapt<WMSTaskDTO>(); |
| | | |
| | | var addResult = await BaseDal.AddDataAsync(task) > 0; |
| | | if (!addResult) |
| | | return WebResponseContent.Instance.Error("ä»»å¡å建失败"); |
| | | return WebResponseContent.Instance.OK("ä»»å¡å建æå", taskDtos); |
| | | }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | if (stockInfo.LocationId > 0 || !string.IsNullOrWhiteSpace(stockInfo.LocationCode)) |
| | | return WebResponseContent.Instance.Error($"æç[{stockPalletCode}]åºåå·²ç»å®è´§ä½ï¼ä¸è½åå»ºæºæ¢°æ{taskName}ä»»å¡"); |
| | | } |
| | | var section = App.Configuration.GetSection("RobotTaskAddressRules").GetSection(targetLineNo).GetChildren().Select(c => c.Value).ToArray(); |
| | | |
| | | var task = new Dt_Task |
| | | { |
| | |
| | | Roadway = stock.Roadway ?? string.Empty, |
| | | TaskType = taskType.GetHashCode(), |
| | | TaskStatus = TaskRobotStatusEnum.RobotNew.GetHashCode(), |
| | | SourceAddress = sourceLineNo, |
| | | TargetAddress = targetLineNo, |
| | | CurrentAddress = sourceLineNo, |
| | | SourceAddress = section[0], |
| | | TargetAddress = section[1], |
| | | CurrentAddress = targetLineNo, |
| | | NextAddress = targetLineNo, |
| | | WarehouseId = stockInfo?.WarehouseId ?? 1, |
| | | Grade = 1, |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å建空æçåºåºä»»å¡ |
| | | /// å建空æçå
¥åºä»»å¡ |
| | | /// </summary> |
| | | /// <param name="taskDto"></param> |
| | | /// <returns></returns> |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 空æçåºåºå®æ |
| | | /// </summary> |
| | | /// <param name="taskDto"></param> |
| | | /// <returns></returns> |
| | | [HttpGet, HttpPost, Route("OutboundFinishTaskTray"), AllowAnonymous] |
| | | public async Task<WebResponseContent?> OutboundFinishTaskTrayAsync([FromBody] CreateTaskDto taskDto) |
| | | { |
| | | return await Service.OutboundFinishTaskTrayAsync(taskDto); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¿®æ¹ä»»å¡ç¶æï¼æ ¹æ®ä»»å¡IDä¿®æ¹ä¸ºæå®ç¶æï¼ |
| | | /// </summary> |
| | | /// <param name="taskDto"></param> |
| | |
| | | "BaseUrl": "http://localhost:5000", |
| | | "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMwMTcyNzM5Mzk5NzYxOTIwIiwibmFtZSI6IlBBQ0voo4XphY3lt6XkvY0wMSIsIkZhY3RvcnlJZCI6IjEyMzQ1NiIsIlNpdGVJZCI6IjEyMzQ1NiIsIkNvZGUiOiJYWExQQUNLMDRBRTAzMiIsIm5iZiI6MTcwNDE4NzY5MCwiZXhwIjoyMTQ1NjkxNjkwLCJpc3MiOiJodHRwczovL3d3dy5oeW1zb24uY29tIiwiYXVkIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSJ9.An1BE7UgfcSP--LtTOmmmWVE2RQFPDahLkDg1xy5KqY" |
| | | }, |
| | | "AGV_OutTaskComplete": "http://localhost:9999/OutTaskComplete", // 䏿¥AGVåºåºè¾éçº¿å®æ |
| | | "RobotTaskAddressRules": { |
| | | "11068": [ "1", "2" ] |
| | | }, |
| | | |
| | | |
| | | "A0GV_OutTaskComplete": "http://localhost:9999/OutTaskComplete", // 䏿¥AGVåºåºè¾éçº¿å®æ |
| | | "WCS_ReceiveTask": "http://localhost:9292/api/Task/ReceiveTask" // WMSè¾é线任å¡ä¸å |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using SqlSugar; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Application.DTOs; |
| | | |
| | | /// <summary> |
| | | /// 设å¤ä¿¡æ¯ DTOï¼æ å° WCS Dt_DeviceInfo è¡¨ï¼ |
| | | /// </summary> |
| | | [SugarTable("Dt_DeviceInfo")] |
| | | public class WcsDeviceDto |
| | | { |
| | | public int Id { get; set; } |
| | | public string DeviceCode { get; set; } = string.Empty; |
| | | public string DeviceName { get; set; } = string.Empty; |
| | | public string DeviceType { get; set; } = string.Empty; |
| | | public string DeviceStatus { get; set; } = string.Empty; |
| | | public string DeviceIp { get; set; } = string.Empty; |
| | | public int DevicePort { get; set; } |
| | | public string DevicePlcType { get; set; } = string.Empty; |
| | | public string DeviceRemark { get; set; } = string.Empty; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设å¤åè®® DTOï¼æ å° WCS Dt_DeviceProtocol è¡¨ï¼ |
| | | /// </summary> |
| | | [SugarTable("Dt_DeviceProtocol")] |
| | | public class WcsDeviceProtocolDto |
| | | { |
| | | public int Id { get; set; } |
| | | public int DeviceId { get; set; } |
| | | public string DeviceChildCode { get; set; } = string.Empty; |
| | | public string DeviceProDataBlock { get; set; } = string.Empty; |
| | | public decimal DeviceProOffset { get; set; } |
| | | public string DeviceProDataType { get; set; } = string.Empty; |
| | | public int DeviceProDataLength { get; set; } |
| | | public string DeviceProParamName { get; set; } = string.Empty; |
| | | public string DeviceProParamType { get; set; } = string.Empty; |
| | | public string DeviceProParamDes { get; set; } = string.Empty; |
| | | public string DeviceProRemark { get; set; } = string.Empty; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Microsoft.Extensions.Options; |
| | | using SqlSugar; |
| | | using WIDESEAWCS_S7Simulator.Application.DTOs; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// 读å WCS æ°æ®åºè®¾å¤æ°æ® |
| | | /// </summary> |
| | | public class DatabaseDeviceService : IDisposable |
| | | { |
| | | private readonly WcsDbOptions _options; |
| | | private readonly ILogger<DatabaseDeviceService> _logger; |
| | | private readonly SqlSugarScope _db; |
| | | |
| | | public DatabaseDeviceService(IOptions<WcsDbOptions> options, ILogger<DatabaseDeviceService> logger) |
| | | { |
| | | _options = options.Value; |
| | | _logger = logger; |
| | | |
| | | _db = new SqlSugarScope(new ConnectionConfig |
| | | { |
| | | ConnectionString = _options.ConnectionString, |
| | | DbType = DbType.SqlServer, |
| | | IsAutoCloseConnection = true, |
| | | InitKeyType = InitKeyType.Attribute |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åææ SiemensS7 ç±»åçè®¾å¤ |
| | | /// </summary> |
| | | public async Task<List<WcsDeviceDto>> GetSiemensS7DevicesAsync() |
| | | { |
| | | try |
| | | { |
| | | var devices = await _db.Queryable<WcsDeviceDto>() |
| | | .Where(d => d.DevicePlcType == "SiemensS7") |
| | | .ToListAsync(); |
| | | _logger.LogInformation("仿°æ®åºè·åå° {Count} 个 SiemensS7 设å¤", devices.Count); |
| | | return devices; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "仿°æ®åºè·å设å¤å¤±è´¥"); |
| | | return new List<WcsDeviceDto>(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæå®è®¾å¤çåè®®å表 |
| | | /// </summary> |
| | | public async Task<List<WcsDeviceProtocolDto>> GetDeviceProtocolsAsync(int deviceId) |
| | | { |
| | | try |
| | | { |
| | | var protocols = await _db.Queryable<WcsDeviceProtocolDto>() |
| | | .Where(p => p.DeviceId == deviceId) |
| | | .ToListAsync(); |
| | | return protocols; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "è·å设å¤å议失败 DeviceId={DeviceId}", deviceId); |
| | | return new List<WcsDeviceProtocolDto>(); |
| | | } |
| | | } |
| | | |
| | | public void Dispose() |
| | | { |
| | | _db.Dispose(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using System.Text.RegularExpressions; |
| | | using WIDESEAWCS_S7Simulator.Application.Protocol; |
| | | using WIDESEAWCS_S7Simulator.Core.Entities; |
| | | using WIDESEAWCS_S7Simulator.Core.Enums; |
| | | using WIDESEAWCS_S7Simulator.Core.Interfaces; |
| | | using WIDESEAWCS_S7Simulator.Core.Protocol; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// å®ä¾åæ¥æå¡ï¼åè°æ°æ®åºè¯»åãå议模æ¿çæãå®ä¾å建 |
| | | /// </summary> |
| | | public class InstanceSyncService |
| | | { |
| | | private readonly DatabaseDeviceService _deviceService; |
| | | private readonly ISimulatorInstanceManager _instanceManager; |
| | | private readonly IProtocolTemplateService _templateService; |
| | | private readonly ILogger<InstanceSyncService> _logger; |
| | | |
| | | private DateTime? _lastSyncTime; |
| | | |
| | | public DateTime? LastSyncTime => _lastSyncTime; |
| | | |
| | | public InstanceSyncService( |
| | | DatabaseDeviceService deviceService, |
| | | ISimulatorInstanceManager instanceManager, |
| | | IProtocolTemplateService templateService, |
| | | ILogger<InstanceSyncService> logger) |
| | | { |
| | | _deviceService = deviceService; |
| | | _instanceManager = instanceManager; |
| | | _templateService = templateService; |
| | | _logger = logger; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ§è¡åæ¥ï¼ä»æ°æ®åºè¯»å设å¤ï¼å建å®ä¾ååè®®æ¨¡æ¿ |
| | | /// </summary> |
| | | public async Task SyncInstancesAsync() |
| | | { |
| | | _logger.LogInformation("å¼å§åæ¥å®ä¾..."); |
| | | _lastSyncTime = DateTime.Now; |
| | | |
| | | // 1. è·åææ SiemensS7 è®¾å¤ |
| | | var devices = await _deviceService.GetSiemensS7DevicesAsync(); |
| | | if (devices.Count == 0) |
| | | { |
| | | _logger.LogWarning("æªæ¾å° SiemensS7 设å¤ï¼åæ¥åæ¶"); |
| | | return; |
| | | } |
| | | |
| | | // 2. è·åç°æå®ä¾IDå表 |
| | | var existingInstanceIds = _instanceManager.GetAllInstances().Select(i => i.Config.Id).ToHashSet(StringComparer.OrdinalIgnoreCase); |
| | | var dbDeviceCodes = devices.Select(d => d.DeviceCode).ToHashSet(StringComparer.OrdinalIgnoreCase); |
| | | |
| | | // 3. æ¸
çå·²ä¸åå¨çå®ä¾ï¼æ°æ®åºä¸æ²¡æä½å
åä¸æï¼ |
| | | foreach (var instanceId in existingInstanceIds) |
| | | { |
| | | if (!dbDeviceCodes.Contains(instanceId)) |
| | | { |
| | | _logger.LogInformation("æ°æ®åºä¸å·²å é¤è®¾å¤ {InstanceId}ï¼ä»å
åç§»é¤", instanceId); |
| | | await _instanceManager.DeleteInstanceAsync(instanceId, deleteConfig: false); |
| | | } |
| | | } |
| | | |
| | | // 4. åå»ºææ´æ°å®ä¾ |
| | | foreach (var device in devices) |
| | | { |
| | | try |
| | | { |
| | | // 4.1 è·å设å¤åè®® |
| | | var protocols = await _deviceService.GetDeviceProtocolsAsync(device.Id); |
| | | |
| | | // é¢è®¡ç®ä¸ä¸ªç¼ååå
¸ï¼å议对象 -> DBç¼å· |
| | | var dbCache = protocols.ToDictionary( |
| | | p => p, |
| | | p => int.TryParse(Regex.Match(p.DeviceProDataBlock, @"\d+").Value, out var n) ? n : 50 |
| | | ); |
| | | |
| | | // 1. è·åå¯ä¸ç¼å·å表 |
| | | var dbNumbers = dbCache.Values.Distinct().ToList(); |
| | | |
| | | // 4.2 å建åè®®æ¨¡æ¿ |
| | | var templateId = $"protocol-{device.DeviceCode}"; |
| | | var template = new ProtocolTemplate |
| | | { |
| | | Id = templateId, |
| | | Name = $"{device.DeviceName} å议模æ¿", |
| | | Version = "1.0", |
| | | Fields = protocols.Select(p => new ProtocolFieldMapping |
| | | { |
| | | FieldKey = $"{p.DeviceChildCode}_{p.DeviceProParamName}", |
| | | DbNumber = dbCache[p], |
| | | Offset = (int)p.DeviceProOffset, |
| | | Bit = 1, |
| | | DataType = MapDataType(p.DeviceProDataType), |
| | | Length = p.DeviceProDataLength, |
| | | Direction = ProtocolFieldDirection.Bidirectional |
| | | }).ToList() |
| | | }; |
| | | await _templateService.UpsertAsync(template); |
| | | |
| | | // 4.3 å建å®ä¾é
ç½® |
| | | var config = new InstanceConfig |
| | | { |
| | | Id = device.DeviceCode, |
| | | Name = device.DeviceName, |
| | | PLCType = SiemensPLCType.S71500, |
| | | Port = device.DevicePort, |
| | | AutoStart = false, |
| | | ProtocolTemplateId = templateId, |
| | | MemoryConfig = GetDefaultMemoryConfig(dbNumbers) |
| | | }; |
| | | |
| | | // 4.4 åå»ºææ´æ°å®ä¾ |
| | | if (_instanceManager.InstanceExists(device.DeviceCode)) |
| | | { |
| | | _logger.LogInformation("å®ä¾ {DeviceCode} å·²åå¨ï¼è·³è¿å建", device.DeviceCode); |
| | | } |
| | | else |
| | | { |
| | | await _instanceManager.CreateInstanceAsync(config); |
| | | _logger.LogInformation("å·²å建å®ä¾ {DeviceCode} (端å£:{Port})", device.DeviceCode, device.DevicePort); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "åæ¥è®¾å¤ {DeviceCode} 失败", device.DeviceCode); |
| | | } |
| | | } |
| | | |
| | | _logger.LogInformation("忥宿"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ°æ®ç±»åæ å°ï¼æ°æ®åºå符串 -> ProtocolDataType æä¸¾ |
| | | /// ProtocolDataType: Byte=0, Int=1, DInt=2, String=3, Bool=4 |
| | | /// </summary> |
| | | private static ProtocolDataType MapDataType(string? dbDataType) |
| | | { |
| | | return dbDataType?.ToLowerInvariant() switch |
| | | { |
| | | "bit" => ProtocolDataType.Bool, // Bool=4 |
| | | "byte" => ProtocolDataType.Byte, // Byte=0 |
| | | "int" or "word" => ProtocolDataType.Int, // Int=1 |
| | | "dint" => ProtocolDataType.DInt, // DInt=2 |
| | | "string" or "string8" or "string16" => ProtocolDataType.String, // String=3 |
| | | _ => ProtocolDataType.Byte |
| | | }; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åé»è®¤å
åé
ç½® |
| | | /// </summary> |
| | | private static MemoryRegionConfig GetDefaultMemoryConfig(List<int> dbBlockNumbers) |
| | | { |
| | | return new MemoryRegionConfig |
| | | { |
| | | MRegionSize = 1024, |
| | | DBBlockCount = dbBlockNumbers.Count, |
| | | DBBlockNumbers = dbBlockNumbers, |
| | | DBBlockSize = 65536, |
| | | IRegionSize = 256, |
| | | QRegionSize = 256, |
| | | TRegionCount = 64, |
| | | CRegionCount = 64 |
| | | }; |
| | | } |
| | | } |
| | |
| | | <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" /> |
| | | <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.5" /> |
| | | <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" /> |
| | | <PackageReference Include="SqlSugarCore" Version="5.1.4.170" /> |
| | | </ItemGroup> |
| | | |
| | | <PropertyGroup> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// WCS æ°æ®åºè¿æ¥é
ç½® |
| | | /// </summary> |
| | | public class WcsDbOptions |
| | | { |
| | | public const string SectionName = "WcsDb"; |
| | | |
| | | /// <summary> |
| | | /// æ¯å¦å¯ç¨æ°æ®åºåæ¥ |
| | | /// </summary> |
| | | public bool Enabled { get; set; } |
| | | |
| | | /// <summary> |
| | | /// è¿æ¥å符串 |
| | | /// </summary> |
| | | public string ConnectionString { get; set; } = string.Empty; |
| | | |
| | | /// <summary> |
| | | /// æ°æ®åºç±»åï¼SqlServer=2, MySql=1 |
| | | /// </summary> |
| | | public int DbType { get; set; } = 2; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Server.Controllers; |
| | | |
| | | [ApiController] |
| | | [Route("api/[controller]")] |
| | | public class SyncController : ControllerBase |
| | | { |
| | | private readonly InstanceSyncService _syncService; |
| | | private readonly ILogger<SyncController> _logger; |
| | | |
| | | public SyncController(InstanceSyncService syncService, ILogger<SyncController> logger) |
| | | { |
| | | _syncService = syncService; |
| | | _logger = logger; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æå¨è§¦åå®ä¾åæ¥ |
| | | /// </summary> |
| | | [HttpPost("SyncInstances")] |
| | | public async Task<IActionResult> SyncInstances() |
| | | { |
| | | try |
| | | { |
| | | _logger.LogInformation("æ¶å°æå¨åæ¥è¯·æ±"); |
| | | await _syncService.SyncInstancesAsync(); |
| | | return Ok(new { message = "忥宿", lastSyncTime = _syncService.LastSyncTime }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "æå¨åæ¥å¤±è´¥"); |
| | | return StatusCode(500, new { message = "åæ¥å¤±è´¥", error = ex.Message }); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·å䏿¬¡åæ¥æ¶é´ |
| | | /// </summary> |
| | | [HttpGet("LastSyncTime")] |
| | | public IActionResult GetLastSyncTime() |
| | | { |
| | | return Ok(new { lastSyncTime = _syncService.LastSyncTime }); |
| | | } |
| | | } |
| ÎļþÃû´Ó Code/²âÊÔ¹¤¾ß/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Server/Data/instance-Line1/config.json ÐÞ¸Ä |
| | |
| | | { |
| | | "id": "Line1", |
| | | "name": "\u4E00\u53F7\u8F93\u9001\u7EBF", |
| | | "id": "1001", |
| | | "name": "A\u533A_\u4E00\u6CE8\u8F93\u9001\u7EBF", |
| | | "plcType": "S71500", |
| | | "port": 105, |
| | | "activationKey": "4b86f3fc-f650-3b08-5924-b0f8278d6ed2", |
| | | "autoStart": true, |
| | | "protocolTemplateId": "wcs-line-v260202", |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-1001", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "id": "1002", |
| | | "name": "A\u533A_\u6362\u76D8\u8F93\u9001\u7EBF", |
| | | "plcType": "S71500", |
| | | "port": 108, |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-1002", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| | | "dbBlockNumbers": [ |
| | | 50 |
| | | ], |
| | | "dbBlockSize": 65536, |
| | | "iRegionSize": 256, |
| | | "qRegionSize": 256, |
| | | "tRegionCount": 64, |
| | | "cRegionCount": 64 |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "id": "1003", |
| | | "name": "A\u533A_\u5E38\u6E29\u8F93\u9001\u7EBF", |
| | | "plcType": "S71500", |
| | | "port": 109, |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-1003", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| | | "dbBlockNumbers": [ |
| | | 50 |
| | | ], |
| | | "dbBlockSize": 65536, |
| | | "iRegionSize": 256, |
| | | "qRegionSize": 256, |
| | | "tRegionCount": 64, |
| | | "cRegionCount": 64 |
| | | } |
| | | } |
| | |
| | | { |
| | | "id": "CWSC1", |
| | | "name": "\u5E38\u6E291\u53F7\u5806\u579B\u673A", |
| | | "name": "\u5E38\u6E29\u5806\u579B\u673A", |
| | | "plcType": "S71500", |
| | | "port": 103, |
| | | "activationKey": "4b86f3fc-f650-3b08-5924-b0f8278d6ed2", |
| | | "autoStart": true, |
| | | "protocolTemplateId": "stacker-interaction-v1", |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-CWSC1", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| | |
| | | { |
| | | "id": "GWSC1", |
| | | "name": "\u9AD8\u6E291\u53F7\u5806\u579B\u673A", |
| | | "name": "\u9AD8\u6E29\u5806\u579B\u673A", |
| | | "plcType": "S71500", |
| | | "port": 102, |
| | | "activationKey": "4b86f3fc-f650-3b08-5924-b0f8278d6ed2", |
| | | "autoStart": true, |
| | | "protocolTemplateId": "stacker-interaction-v1", |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-GWSC1", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| | |
| | | { |
| | | "id": "HCSC1", |
| | | "name": "\u5316\u62101\u53F7\u5806\u579B\u673A", |
| | | "name": "\u5316\u6210\u5806\u579B\u673A", |
| | | "plcType": "S71500", |
| | | "port": 104, |
| | | "activationKey": "4b86f3fc-f650-3b08-5924-b0f8278d6ed2", |
| | | "autoStart": true, |
| | | "protocolTemplateId": "plclink-stacker-v1", |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-HCSC1", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 2, |
| | | "dbBlockNumbers": [ |
| | | 900, |
| | | 910 |
| | | 910, |
| | | 900 |
| | | ], |
| | | "dbBlockSize": 65536, |
| | | "iRegionSize": 256, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "id": "PM", |
| | | "name": "\u63D2\u62D4\u9489\u673A", |
| | | "plcType": "S71500", |
| | | "port": 107, |
| | | "activationKey": "", |
| | | "autoStart": false, |
| | | "protocolTemplateId": "protocol-PM", |
| | | "memoryConfig": { |
| | | "mRegionSize": 1024, |
| | | "dbBlockCount": 1, |
| | | "dbBlockNumbers": [ |
| | | 600 |
| | | ], |
| | | "dbBlockSize": 65536, |
| | | "iRegionSize": 256, |
| | | "qRegionSize": 256, |
| | | "tRegionCount": 64, |
| | | "cRegionCount": 64 |
| | | } |
| | | } |
| | |
| | | [ |
| | | { |
| | | "id": "wcs-line-v260202", |
| | | "name": "WCS-\u8F93\u9001\u7EBF\u5BF9\u63A5\u534F\u8BAE V260202", |
| | | "version": "V260202", |
| | | "id": "protocol-GWSC1", |
| | | "name": "\u9AD8\u6E29\u5806\u579B\u673A \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "GWSC01_InputTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 194, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_WorkAction", |
| | | "dbNumber": 100, |
| | | "offset": 192, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputWorkType", |
| | | "dbNumber": 100, |
| | | "offset": 198, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPickRow", |
| | | "dbNumber": 100, |
| | | "offset": 208, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPickColumn", |
| | | "dbNumber": 100, |
| | | "offset": 210, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPickLayer", |
| | | "dbNumber": 100, |
| | | "offset": 212, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPlaceRow", |
| | | "dbNumber": 100, |
| | | "offset": 214, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPlaceColumn", |
| | | "dbNumber": 100, |
| | | "offset": 216, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_InputPlaceLayer", |
| | | "dbNumber": 100, |
| | | "offset": 218, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_StackerCraneAutoStatus", |
| | | "dbNumber": 100, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_StackerCraneWorkStatus", |
| | | "dbNumber": 100, |
| | | "offset": 4, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_OutputFaultHigh", |
| | | "dbNumber": 100, |
| | | "offset": 12, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_OutputFaultMid", |
| | | "dbNumber": 100, |
| | | "offset": 16, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_OutputFaultLow", |
| | | "dbNumber": 100, |
| | | "offset": 20, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_CurrentTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 24, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_StackerCraneCompleted", |
| | | "dbNumber": 100, |
| | | "offset": 28, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_OutputCurrentColumn", |
| | | "dbNumber": 100, |
| | | "offset": 46, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_OutputCurrentLayer", |
| | | "dbNumber": 100, |
| | | "offset": 48, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "GWSC01_StackerCraneStatus", |
| | | "dbNumber": 100, |
| | | "offset": 96, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "protocol-HCSC1", |
| | | "name": "\u5316\u6210\u5806\u579B\u673A \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneHeartBeat", |
| | | "dbNumber": 910, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneStatus", |
| | | "dbNumber": 910, |
| | | "offset": 6, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneFaultCode", |
| | | "dbNumber": 910, |
| | | "offset": 8, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneWorkStatus", |
| | | "dbNumber": 910, |
| | | "offset": 20, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneRow", |
| | | "dbNumber": 910, |
| | | "offset": 22, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneColumn", |
| | | "dbNumber": 910, |
| | | "offset": 24, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneLayer", |
| | | "dbNumber": 910, |
| | | "offset": 26, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_CurrentTaskNum", |
| | | "dbNumber": 910, |
| | | "offset": 28, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneWorkAction", |
| | | "dbNumber": 910, |
| | | "offset": 40, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StackerCraneCompleted", |
| | | "dbNumber": 910, |
| | | "offset": 42, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_HeartBeat", |
| | | "dbNumber": 900, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_TaskNum", |
| | | "dbNumber": 900, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_WorkAction", |
| | | "dbNumber": 900, |
| | | "offset": 40, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_FireAlarm", |
| | | "dbNumber": 900, |
| | | "offset": 42, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_WorkType", |
| | | "dbNumber": 900, |
| | | "offset": 44, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StartRow", |
| | | "dbNumber": 900, |
| | | "offset": 46, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StartColumn", |
| | | "dbNumber": 900, |
| | | "offset": 48, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_StartLayer", |
| | | "dbNumber": 900, |
| | | "offset": 50, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_EndRow", |
| | | "dbNumber": 900, |
| | | "offset": 52, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_EndColumn", |
| | | "dbNumber": 900, |
| | | "offset": 54, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_EndLayer", |
| | | "dbNumber": 900, |
| | | "offset": 56, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "HCSC01_Barcode", |
| | | "dbNumber": 900, |
| | | "offset": 58, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 26, |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "protocol-CWSC1", |
| | | "name": "\u5E38\u6E29\u5806\u579B\u673A \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "CWSC01_InputTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 194, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_WorkAction", |
| | | "dbNumber": 100, |
| | | "offset": 192, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputWorkType", |
| | | "dbNumber": 100, |
| | | "offset": 198, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPickRow", |
| | | "dbNumber": 100, |
| | | "offset": 208, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPickColumn", |
| | | "dbNumber": 100, |
| | | "offset": 210, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPickLayer", |
| | | "dbNumber": 100, |
| | | "offset": 212, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPlaceRow", |
| | | "dbNumber": 100, |
| | | "offset": 214, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPlaceColumn", |
| | | "dbNumber": 100, |
| | | "offset": 216, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_InputPlaceLayer", |
| | | "dbNumber": 100, |
| | | "offset": 218, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_StackerCraneAutoStatus", |
| | | "dbNumber": 100, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_StackerCraneWorkStatus", |
| | | "dbNumber": 100, |
| | | "offset": 4, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_OutputFaultHigh", |
| | | "dbNumber": 100, |
| | | "offset": 12, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_OutputFaultMid", |
| | | "dbNumber": 100, |
| | | "offset": 16, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_OutputFaultLow", |
| | | "dbNumber": 100, |
| | | "offset": 20, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_CurrentTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 24, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_StackerCraneCompleted", |
| | | "dbNumber": 100, |
| | | "offset": 28, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_OutputCurrentColumn", |
| | | "dbNumber": 100, |
| | | "offset": 46, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_OutputCurrentLayer", |
| | | "dbNumber": 100, |
| | | "offset": 48, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "CWSC01_StackerCraneStatus", |
| | | "dbNumber": 100, |
| | | "offset": 96, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "protocol-1001", |
| | | "name": "A\u533A_\u4E00\u6CE8\u8F93\u9001\u7EBF \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "11028_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_Source", |
| | | "dbNumber": 50, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_Target", |
| | | "dbNumber": 50, |
| | | "offset": 4, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 6, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 7, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 8, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 9, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 10, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 11, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 12, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 13, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 14, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 15, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 16, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 17, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11028_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 18, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 560, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_Source", |
| | | "dbNumber": 50, |
| | | "offset": 562, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_Target", |
| | | "dbNumber": 50, |
| | | "offset": 564, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 566, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 567, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 568, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 569, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 570, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 571, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 572, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 573, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 574, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 575, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 576, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 577, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11042_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 578, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 1360, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_Source", |
| | | "dbNumber": 50, |
| | | "offset": 1362, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_Target", |
| | | "dbNumber": 50, |
| | | "offset": 1364, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 1366, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 1367, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1368, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1369, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1370, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1371, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1372, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 1373, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1374, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 1375, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 1376, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 1377, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11062_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 1378, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 1600, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_Source", |
| | | "dbNumber": 50, |
| | | "offset": 1602, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_Target", |
| | | "dbNumber": 50, |
| | | "offset": 1604, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 1606, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 1607, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1608, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1609, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1610, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1611, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1612, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 1613, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1614, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 1615, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 1616, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 1617, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11068_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 1618, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "protocol-PM", |
| | | "name": "\u63D2\u62D4\u9489\u673A \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "PinMachine_LogisticsLineRunningSignal", |
| | | "dbNumber": 600, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_PlugPinMachineRunningSignal", |
| | | "dbNumber": 600, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_MaterialRequestUpper", |
| | | "dbNumber": 600, |
| | | "offset": 4, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_OutputRequestUpper", |
| | | "dbNumber": 600, |
| | | "offset": 6, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_PlugPinTrayOutputReadyUpper", |
| | | "dbNumber": 600, |
| | | "offset": 8, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_MaterialRequestLower", |
| | | "dbNumber": 600, |
| | | "offset": 10, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_OutputRequestLower", |
| | | "dbNumber": 600, |
| | | "offset": 12, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "PinMachine_PlugPinTrayOutputReadyLower", |
| | | "dbNumber": 600, |
| | | "offset": 14, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "protocol-1002", |
| | | "name": "A\u533A_\u6362\u76D8\u8F93\u9001\u7EBF \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "11001_TaskNo", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_WCS_STB", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_WCS_ACK", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_PLC_STB", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_PLC_ACK", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_PLC_REQ", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_WCS_ERRCode", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_WCS_Special", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_Equ_Auto", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_Last_pallet", |
| | |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11001_Barcode", |
| | |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 450, |
| | | "offset": 400, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_Source", |
| | | "dbNumber": 50, |
| | | "offset": 452, |
| | | "offset": 402, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_Target", |
| | | "dbNumber": 50, |
| | | "offset": 454, |
| | | "offset": 404, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 456, |
| | | "offset": 406, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 457, |
| | | "offset": 407, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 458, |
| | | "offset": 408, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 459, |
| | | "offset": 409, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 460, |
| | | "offset": 410, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 461, |
| | | "offset": 411, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 462, |
| | | "offset": 412, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 463, |
| | | "offset": 413, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 464, |
| | | "offset": 414, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 465, |
| | | "offset": 415, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 466, |
| | | "offset": 416, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 467, |
| | | "offset": 417, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11010_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 468, |
| | | "offset": 418, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 950, |
| | | "offset": 800, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_Source", |
| | | "dbNumber": 50, |
| | | "offset": 952, |
| | | "offset": 802, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_Target", |
| | | "dbNumber": 50, |
| | | "offset": 954, |
| | | "offset": 804, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 956, |
| | | "offset": 806, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 957, |
| | | "offset": 807, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 958, |
| | | "offset": 808, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 959, |
| | | "offset": 809, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 960, |
| | | "offset": 810, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 961, |
| | | "offset": 811, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 962, |
| | | "offset": 812, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 963, |
| | | "offset": 813, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 964, |
| | | "offset": 814, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 965, |
| | | "offset": 815, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 966, |
| | | "offset": 816, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 967, |
| | | "offset": 817, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11020_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 968, |
| | | "offset": 818, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 1250, |
| | | "offset": 1040, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_Source", |
| | | "dbNumber": 50, |
| | | "offset": 1252, |
| | | "offset": 1042, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_Target", |
| | | "dbNumber": 50, |
| | | "offset": 1254, |
| | | "offset": 1044, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 1256, |
| | | "offset": 1046, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 1257, |
| | | "offset": 1047, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1258, |
| | | "offset": 1048, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1259, |
| | | "offset": 1049, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1260, |
| | | "offset": 1050, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 1261, |
| | | "offset": 1051, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 1262, |
| | | "offset": 1052, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 1263, |
| | | "offset": 1053, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 1264, |
| | | "offset": 1054, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 1265, |
| | | "offset": 1055, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 1266, |
| | | "offset": 1056, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 1267, |
| | | "offset": 1057, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "11026_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 1268, |
| | | "offset": 1058, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 0 |
| | | "direction": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "plclink-stacker-v1", |
| | | "name": "\u5316\u6210\u5806\u579B\u673A", |
| | | "version": "2026.03", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "StackerCraneHeartBeat", |
| | | "dbNumber": 910, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneStatus", |
| | | "dbNumber": 910, |
| | | "offset": 6, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneFaultCode", |
| | | "dbNumber": 910, |
| | | "offset": 8, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneWorkStatus", |
| | | "dbNumber": 910, |
| | | "offset": 20, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneRow", |
| | | "dbNumber": 910, |
| | | "offset": 22, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneColumn", |
| | | "dbNumber": 910, |
| | | "offset": 24, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneLayer", |
| | | "dbNumber": 910, |
| | | "offset": 26, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "CurrentTaskNum", |
| | | "dbNumber": 910, |
| | | "offset": 28, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneWorkAction", |
| | | "dbNumber": 910, |
| | | "offset": 40, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneCompleted", |
| | | "dbNumber": 910, |
| | | "offset": 42, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "HeartBeat", |
| | | "dbNumber": 900, |
| | | "offset": 0, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "TaskNum", |
| | | "dbNumber": 900, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "WorkAction", |
| | | "dbNumber": 900, |
| | | "offset": 40, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "FireAlarm", |
| | | "dbNumber": 900, |
| | | "offset": 42, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "WorkType", |
| | | "dbNumber": 900, |
| | | "offset": 44, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "StartRow", |
| | | "dbNumber": 900, |
| | | "offset": 46, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "StartColumn", |
| | | "dbNumber": 900, |
| | | "offset": 48, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "StartLayer", |
| | | "dbNumber": 900, |
| | | "offset": 50, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "EndRow", |
| | | "dbNumber": 900, |
| | | "offset": 52, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "EndColumn", |
| | | "dbNumber": 900, |
| | | "offset": 54, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "EndLayer", |
| | | "dbNumber": 900, |
| | | "offset": 56, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "Barcode", |
| | | "dbNumber": 900, |
| | | "offset": 58, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 26, |
| | | "direction": 0 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "stacker-interaction-v1", |
| | | "name": "\u9AD8\u5E38\u6E29\u5806\u579B\u673A", |
| | | "version": "2026.03", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "InputTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 194, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "WorkAction", |
| | | "dbNumber": 100, |
| | | "offset": 192, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputWorkType", |
| | | "dbNumber": 100, |
| | | "offset": 198, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPickRow", |
| | | "dbNumber": 100, |
| | | "offset": 208, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPickColumn", |
| | | "dbNumber": 100, |
| | | "offset": 210, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPickLayer", |
| | | "dbNumber": 100, |
| | | "offset": 212, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPlaceRow", |
| | | "dbNumber": 100, |
| | | "offset": 214, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPlaceColumn", |
| | | "dbNumber": 100, |
| | | "offset": 216, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "InputPlaceLayer", |
| | | "dbNumber": 100, |
| | | "offset": 218, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 0 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneAutoStatus", |
| | | "dbNumber": 100, |
| | | "offset": 2, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneWorkStatus", |
| | | "dbNumber": 100, |
| | | "offset": 4, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "OutputFaultHigh", |
| | | "dbNumber": 100, |
| | | "offset": 12, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "OutputFaultMid", |
| | | "dbNumber": 100, |
| | | "offset": 16, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "OutputFaultLow", |
| | | "dbNumber": 100, |
| | | "offset": 20, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "CurrentTaskNum", |
| | | "dbNumber": 100, |
| | | "offset": 24, |
| | | "bit": 1, |
| | | "dataType": 2, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneCompleted", |
| | | "dbNumber": 100, |
| | | "offset": 28, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "OutputCurrentColumn", |
| | | "dbNumber": 100, |
| | | "offset": 46, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "OutputCurrentLayer", |
| | | "dbNumber": 100, |
| | | "offset": 48, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | }, |
| | | { |
| | | "fieldKey": "StackerCraneStatus", |
| | | "dbNumber": 100, |
| | | "offset": 96, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 1 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "wcs-line-hcline", |
| | | "name": "WCS-\u5316\u6210\u6BB5\u8F93\u9001\u7EBF", |
| | | "id": "protocol-1003", |
| | | "name": "A\u533A_\u5E38\u6E29\u8F93\u9001\u7EBF \u534F\u8BAE\u6A21\u677F", |
| | | "version": "1.0", |
| | | "fields": [ |
| | | { |
| | | "fieldKey": "10010_TaskNo", |
| | | "fieldKey": "11070_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 0, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_Source", |
| | | "fieldKey": "11070_Source", |
| | | "dbNumber": 50, |
| | | "offset": 2, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_Target", |
| | | "fieldKey": "11070_Target", |
| | | "dbNumber": 50, |
| | | "offset": 4, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_BoxType", |
| | | "fieldKey": "11070_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 6, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_CV_State", |
| | | "fieldKey": "11070_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 7, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_CV_ERRCode", |
| | | "fieldKey": "11070_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 8, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_WCS_STB", |
| | | "fieldKey": "11070_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 9, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_WCS_ACK", |
| | | "fieldKey": "11070_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 10, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_PLC_STB", |
| | | "fieldKey": "11070_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 11, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_PLC_ACK", |
| | | "fieldKey": "11070_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 12, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_PLC_REQ", |
| | | "fieldKey": "11070_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 13, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_WCS_ERRCode", |
| | | "fieldKey": "11070_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 14, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_WCS_Special", |
| | | "fieldKey": "11070_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 15, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_Equ_Auto", |
| | | "fieldKey": "11070_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 16, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_Last_pallet", |
| | | "fieldKey": "11070_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 17, |
| | | "bit": 1, |
| | |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10010_Barcode", |
| | | "fieldKey": "11070_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 18, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "length": 20, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_TaskNo", |
| | | "fieldKey": "11078_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 50, |
| | | "offset": 320, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_Source", |
| | | "fieldKey": "11078_Source", |
| | | "dbNumber": 50, |
| | | "offset": 52, |
| | | "offset": 322, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_Target", |
| | | "fieldKey": "11078_Target", |
| | | "dbNumber": 50, |
| | | "offset": 54, |
| | | "offset": 324, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_BoxType", |
| | | "fieldKey": "11078_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 56, |
| | | "offset": 326, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_CV_State", |
| | | "fieldKey": "11078_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 57, |
| | | "offset": 327, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_CV_ERRCode", |
| | | "fieldKey": "11078_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 58, |
| | | "offset": 328, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_WCS_STB", |
| | | "fieldKey": "11078_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 59, |
| | | "offset": 329, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_WCS_ACK", |
| | | "fieldKey": "11078_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 60, |
| | | "offset": 330, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_PLC_STB", |
| | | "fieldKey": "11078_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 61, |
| | | "offset": 331, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_PLC_ACK", |
| | | "fieldKey": "11078_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 62, |
| | | "offset": 332, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_PLC_REQ", |
| | | "fieldKey": "11078_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 63, |
| | | "offset": 333, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_WCS_ERRCode", |
| | | "fieldKey": "11078_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 64, |
| | | "offset": 334, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_WCS_Special", |
| | | "fieldKey": "11078_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 65, |
| | | "offset": 335, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_Equ_Auto", |
| | | "fieldKey": "11078_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 66, |
| | | "offset": 336, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_Last_pallet", |
| | | "fieldKey": "11078_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 67, |
| | | "offset": 337, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10030_Barcode", |
| | | "fieldKey": "11078_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 68, |
| | | "offset": 338, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "length": 20, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_TaskNo", |
| | | "fieldKey": "11085_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 100, |
| | | "offset": 600, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_Source", |
| | | "fieldKey": "11085_Source", |
| | | "dbNumber": 50, |
| | | "offset": 102, |
| | | "offset": 602, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_Target", |
| | | "fieldKey": "11085_Target", |
| | | "dbNumber": 50, |
| | | "offset": 104, |
| | | "offset": 604, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_BoxType", |
| | | "fieldKey": "11085_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 106, |
| | | "offset": 606, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_CV_State", |
| | | "fieldKey": "11085_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 107, |
| | | "offset": 607, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_CV_ERRCode", |
| | | "fieldKey": "11085_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 108, |
| | | "offset": 608, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_WCS_STB", |
| | | "fieldKey": "11085_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 109, |
| | | "offset": 609, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_WCS_ACK", |
| | | "fieldKey": "11085_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 110, |
| | | "offset": 610, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_PLC_STB", |
| | | "fieldKey": "11085_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 111, |
| | | "offset": 611, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_PLC_ACK", |
| | | "fieldKey": "11085_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 112, |
| | | "offset": 612, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_PLC_REQ", |
| | | "fieldKey": "11085_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 113, |
| | | "offset": 613, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_WCS_ERRCode", |
| | | "fieldKey": "11085_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 114, |
| | | "offset": 614, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_WCS_Special", |
| | | "fieldKey": "11085_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 115, |
| | | "offset": 615, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_Equ_Auto", |
| | | "fieldKey": "11085_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 116, |
| | | "offset": 616, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_Last_pallet", |
| | | "fieldKey": "11085_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 117, |
| | | "offset": 617, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10180_Barcode", |
| | | "fieldKey": "11085_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 118, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 150, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_Source", |
| | | "dbNumber": 50, |
| | | "offset": 152, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_Target", |
| | | "dbNumber": 50, |
| | | "offset": 154, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 156, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 157, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 158, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 159, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 160, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 161, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 162, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 163, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 164, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 165, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 166, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 167, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10190_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 168, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 200, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_Source", |
| | | "dbNumber": 50, |
| | | "offset": 202, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_Target", |
| | | "dbNumber": 50, |
| | | "offset": 204, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 206, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 207, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 208, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 209, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 210, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 211, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 212, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 213, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 214, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 215, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 216, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 217, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "10250_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 218, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 250, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_Source", |
| | | "dbNumber": 50, |
| | | "offset": 252, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_Target", |
| | | "dbNumber": 50, |
| | | "offset": 254, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 256, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 257, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 258, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 259, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 260, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 261, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 262, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 263, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 264, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 265, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 266, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 267, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20090_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 268, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 300, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_Source", |
| | | "dbNumber": 50, |
| | | "offset": 302, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_Target", |
| | | "dbNumber": 50, |
| | | "offset": 304, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 306, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 307, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 308, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 309, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 310, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 311, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 312, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 313, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 314, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 315, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 316, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 317, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20100_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 318, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_TaskNo", |
| | | "dbNumber": 50, |
| | | "offset": 350, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_Source", |
| | | "dbNumber": 50, |
| | | "offset": 352, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_Target", |
| | | "dbNumber": 50, |
| | | "offset": 354, |
| | | "bit": 1, |
| | | "dataType": 1, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_BoxType", |
| | | "dbNumber": 50, |
| | | "offset": 356, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_CV_State", |
| | | "dbNumber": 50, |
| | | "offset": 357, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_CV_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 358, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_WCS_STB", |
| | | "dbNumber": 50, |
| | | "offset": 359, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_WCS_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 360, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_PLC_STB", |
| | | "dbNumber": 50, |
| | | "offset": 361, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_PLC_ACK", |
| | | "dbNumber": 50, |
| | | "offset": 362, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_PLC_REQ", |
| | | "dbNumber": 50, |
| | | "offset": 363, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_WCS_ERRCode", |
| | | "dbNumber": 50, |
| | | "offset": 364, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_WCS_Special", |
| | | "dbNumber": 50, |
| | | "offset": 365, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_Equ_Auto", |
| | | "dbNumber": 50, |
| | | "offset": 366, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_Last_pallet", |
| | | "dbNumber": 50, |
| | | "offset": 367, |
| | | "bit": 1, |
| | | "dataType": 0, |
| | | "length": 1, |
| | | "direction": 2 |
| | | }, |
| | | { |
| | | "fieldKey": "20170_Barcode", |
| | | "dbNumber": 50, |
| | | "offset": 368, |
| | | "offset": 618, |
| | | "bit": 1, |
| | | "dataType": 3, |
| | | "length": 22, |
| | |
| | | using WIDESEAWCS_S7Simulator.Core.Entities; |
| | | using System.Text.Json.Serialization; |
| | | using WIDESEAWCS_S7Simulator.Application.Protocol; |
| | | using WIDESEAWCS_S7Simulator.Application; |
| | | using Microsoft.Extensions.Options; |
| | | using WIDESEAWCS_S7Simulator.Server.Services; |
| | | |
| | | var builder = WebApplication.CreateBuilder(args); |
| | |
| | | |
| | | // Register core services |
| | | builder.Services.AddSingleton<ISimulatorInstanceManager, SimulatorInstanceManager>(); |
| | | |
| | | // WCS æ°æ®åºé
ç½® |
| | | builder.Services.Configure<WcsDbOptions>(builder.Configuration.GetSection(WcsDbOptions.SectionName)); |
| | | builder.Services.AddSingleton<DatabaseDeviceService>(); |
| | | builder.Services.AddSingleton<InstanceSyncService>(); |
| | | |
| | | // Get content root path for data directory |
| | | var contentRoot = builder.Environment.ContentRootPath; |
| | |
| | | |
| | | // å¯å¨æ¶å 载已ä¿åçå®ä¾ï¼ä¸èªå¨å¯å¨ï¼ |
| | | var instanceManager = app.Services.GetRequiredService<ISimulatorInstanceManager>(); |
| | | var syncService = app.Services.GetRequiredService<InstanceSyncService>(); |
| | | _ = Task.Run(async () => |
| | | { |
| | | try |
| | | { |
| | | // å
å 载已ä¿åçå®ä¾ |
| | | await instanceManager.LoadSavedInstancesAsync(autoStart: false); |
| | | Console.WriteLine($"Loaded {instanceManager.GetAllInstances().Count()} saved instances."); |
| | | |
| | | // 妿å¯ç¨äº WCS æ°æ®åºåæ¥ï¼åæ§è¡åæ¥ |
| | | var wcsDbOptions = app.Services.GetRequiredService<IOptions<WcsDbOptions>>().Value; |
| | | if (wcsDbOptions.Enabled) |
| | | { |
| | | await syncService.SyncInstancesAsync(); |
| | | Console.WriteLine($"WCS DB sync completed. Last sync: {syncService.LastSyncTime}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"Error loading saved instances: {ex.Message}"); |
| | | Console.WriteLine($"Error during startup: {ex.Message}"); |
| | | } |
| | | }); |
| | | |
| | |
| | | } |
| | | ] |
| | | }, |
| | | "AllowedHosts": "*" |
| | | "WcsDb": { |
| | | "Enabled": true, |
| | | "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", |
| | | "DbType": 2 |
| | | }, |
| | | "AllowedHosts": "*" |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # S7 模æå¨æ°æ®åºå®ä¾åæ¥å®ç°è®¡å |
| | | |
| | | > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. |
| | | |
| | | **Goal:** ä» WCS æ°æ®åºèªå¨åæ¥è®¾å¤å° S7 模æå¨å®ä¾ï¼å¯å¨æ¶åæ¥ä¸æ¬¡ï¼ä¹æ¯æ API æå¨è§¦å |
| | | |
| | | **Architecture:** å¨ Application 屿°å¢ DatabaseDeviceService 读å WCS æ°æ®åºï¼InstanceSyncService åè°åæ¥é»è¾ï¼SimulatorInstanceManager å建/管çå®ä¾ãå议模æ¿éè¿ç°æ IProtocolTemplateService ä¿åå°æ¬å° JSON æä»¶ã |
| | | |
| | | **Tech Stack:** .NET 6, SqlSugarCore, ASP.NET Core, JSON æä»¶æä¹
å |
| | | |
| | | --- |
| | | |
| | | ## æä»¶ç»æ |
| | | |
| | | ``` |
| | | Application/ |
| | | âââ DTOs/ |
| | | â âââ WcsDeviceDto.cs # æ°æ®åºå段æ å° DTO |
| | | âââ WcsDbOptions.cs # WCS æ°æ®åºé
ç½® |
| | | âââ DatabaseDeviceService.cs # 读å WCS æ°æ®åº |
| | | âââ InstanceSyncService.cs # 忥åè°é»è¾ |
| | | |
| | | Server/ |
| | | âââ Controllers/ |
| | | â âââ SyncController.cs # API æ¥å£ |
| | | âââ appsettings.json # æ·»å WcsDb é
ç½® |
| | | âââ Program.cs # 注åæå¡ãå¯å¨åæ¥ |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 1: æ·»å SqlSugarCore ä¾èµ |
| | | |
| | | **Files:** |
| | | - Modify: `WIDESEAWCS_S7Simulator.Application/WIDESEAWCS_S7Simulator.Application.csproj` |
| | | |
| | | - [ ] **Step 1: æ·»å SqlSugarCore NuGet å
** |
| | | |
| | | ```xml |
| | | <PackageReference Include="SqlSugarCore" Version="5.1.4.170" /> |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Application/WIDESEAWCS_S7Simulator.Application.csproj |
| | | git commit -m "feat: æ·»å SqlSugarCore ä¾èµç¨äºæ°æ®åºè¿æ¥" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 2: å建 WCS æ°æ®åº DTO |
| | | |
| | | **Files:** |
| | | - Create: `WIDESEAWCS_S7Simulator.Application/DTOs/WcsDeviceDto.cs` |
| | | |
| | | - [ ] **Step 1: å建 WcsDeviceDto.cs** |
| | | |
| | | ```csharp |
| | | namespace WIDESEAWCS_S7Simulator.Application.DTOs; |
| | | |
| | | /// <summary> |
| | | /// 设å¤ä¿¡æ¯ DTOï¼æ å° WCS Dt_DeviceInfo è¡¨ï¼ |
| | | /// </summary> |
| | | public class WcsDeviceDto |
| | | { |
| | | public int Id { get; set; } |
| | | public string DeviceCode { get; set; } = string.Empty; |
| | | public string DeviceName { get; set; } = string.Empty; |
| | | public string DeviceType { get; set; } = string.Empty; |
| | | public string DeviceStatus { get; set; } = string.Empty; |
| | | public string DeviceIp { get; set; } = string.Empty; |
| | | public int DevicePort { get; set; } |
| | | public string DevicePlcType { get; set; } = string.Empty; |
| | | public string DeviceRemark { get; set; } = string.Empty; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设å¤åè®® DTOï¼æ å° WCS Dt_DeviceProtocol è¡¨ï¼ |
| | | /// </summary> |
| | | public class WcsDeviceProtocolDto |
| | | { |
| | | public int Id { get; set; } |
| | | public int DeviceId { get; set; } |
| | | public string DeviceChildCode { get; set; } = string.Empty; |
| | | public string DeviceProDataBlock { get; set; } = string.Empty; |
| | | public decimal DeviceProOffset { get; set; } |
| | | public string DeviceProDataType { get; set; } = string.Empty; |
| | | public int DeviceProDataLength { get; set; } |
| | | public string DeviceProParamName { get; set; } = string.Empty; |
| | | public string DeviceProParamType { get; set; } = string.Empty; |
| | | public string DeviceProParamDes { get; set; } = string.Empty; |
| | | public string DeviceProRemark { get; set; } = string.Empty; |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Application/DTOs/WcsDeviceDto.cs |
| | | git commit -m "feat: æ·»å WCS è®¾å¤ DTO" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 3: å建 WcsDbOptions é
置类 |
| | | |
| | | **Files:** |
| | | - Create: `WIDESEAWCS_S7Simulator.Application/WcsDbOptions.cs` |
| | | |
| | | - [ ] **Step 1: å建 WcsDbOptions.cs** |
| | | |
| | | ```csharp |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// WCS æ°æ®åºè¿æ¥é
ç½® |
| | | /// </summary> |
| | | public class WcsDbOptions |
| | | { |
| | | public const string SectionName = "WcsDb"; |
| | | |
| | | /// <summary> |
| | | /// æ¯å¦å¯ç¨æ°æ®åºåæ¥ |
| | | /// </summary> |
| | | public bool Enabled { get; set; } |
| | | |
| | | /// <summary> |
| | | /// è¿æ¥å符串 |
| | | /// </summary> |
| | | public string ConnectionString { get; set; } = string.Empty; |
| | | |
| | | /// <summary> |
| | | /// æ°æ®åºç±»åï¼SqlServer=2, MySql=1 |
| | | /// </summary> |
| | | public int DbType { get; set; } = 2; |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Application/WcsDbOptions.cs |
| | | git commit -m "feat: æ·»å WcsDbOptions é
置类" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 4: å建 DatabaseDeviceService |
| | | |
| | | **Files:** |
| | | - Create: `WIDESEAWCS_S7Simulator.Application/DatabaseDeviceService.cs` |
| | | |
| | | - [ ] **Step 1: å建 DatabaseDeviceService.cs** |
| | | |
| | | ```csharp |
| | | using Microsoft.Extensions.Logging; |
| | | using Microsoft.Extensions.Options; |
| | | using SqlSugar; |
| | | using WIDESEAWCS_S7Simulator.Application.DTOs; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// 读å WCS æ°æ®åºè®¾å¤æ°æ® |
| | | /// </summary> |
| | | public class DatabaseDeviceService : IDisposable |
| | | { |
| | | private readonly WcsDbOptions _options; |
| | | private readonly ILogger<DatabaseDeviceService> _logger; |
| | | private readonly SqlSugarScope _db; |
| | | |
| | | public DatabaseDeviceService(IOptions<WcsDbOptions> options, ILogger<DatabaseDeviceService> logger) |
| | | { |
| | | _options = options.Value; |
| | | _logger = logger; |
| | | |
| | | _db = new SqlSugarScope(new ConnectionConfig |
| | | { |
| | | ConnectionString = _options.ConnectionString, |
| | | DbType = (DbType)_options.DbType, |
| | | IsAutoCloseConnection = true, |
| | | InitKeyType = InitKeyType.Attribute |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åææ SiemensS7 ç±»åçè®¾å¤ |
| | | /// </summary> |
| | | public async Task<List<WcsDeviceDto>> GetSiemensS7DevicesAsync() |
| | | { |
| | | try |
| | | { |
| | | var devices = await _db.Queryable<WcsDeviceDto>() |
| | | .Where(d => d.DevicePlcType == "SiemensS7") |
| | | .ToListAsync(); |
| | | _logger.LogInformation("仿°æ®åºè·åå° {Count} 个 SiemensS7 设å¤", devices.Count); |
| | | return devices; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "仿°æ®åºè·å设å¤å¤±è´¥"); |
| | | return new List<WcsDeviceDto>(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæå®è®¾å¤çåè®®å表 |
| | | /// </summary> |
| | | public async Task<List<WcsDeviceProtocolDto>> GetDeviceProtocolsAsync(int deviceId) |
| | | { |
| | | try |
| | | { |
| | | var protocols = await _db.Queryable<WcsDeviceProtocolDto>() |
| | | .Where(p => p.DeviceId == deviceId) |
| | | .ToListAsync(); |
| | | return protocols; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "è·å设å¤å议失败 DeviceId={DeviceId}", deviceId); |
| | | return new List<WcsDeviceProtocolDto>(); |
| | | } |
| | | } |
| | | |
| | | public void Dispose() |
| | | { |
| | | _db.Dispose(); |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Application/DatabaseDeviceService.cs |
| | | git commit -m "feat: æ·»å DatabaseDeviceService 读å WCS æ°æ®åº" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 5: å建 InstanceSyncService |
| | | |
| | | **Files:** |
| | | - Create: `WIDESEAWCS_S7Simulator.Application/InstanceSyncService.cs` |
| | | |
| | | - [ ] **Step 1: å建 InstanceSyncService.cs** |
| | | |
| | | ```csharp |
| | | using Microsoft.Extensions.Logging; |
| | | using WIDESEAWCS_S7Simulator.Application.Protocol; |
| | | using WIDESEAWCS_S7Simulator.Core.Entities; |
| | | using WIDESEAWCS_S7Simulator.Core.Enums; |
| | | using WIDESEAWCS_S7Simulator.Core.Interfaces; |
| | | using WIDESEAWCS_S7Simulator.Core.Protocol; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | /// <summary> |
| | | /// å®ä¾åæ¥æå¡ï¼åè°æ°æ®åºè¯»åãå议模æ¿çæãå®ä¾å建 |
| | | /// </summary> |
| | | public class InstanceSyncService |
| | | { |
| | | private readonly DatabaseDeviceService _deviceService; |
| | | private readonly ISimulatorInstanceManager _instanceManager; |
| | | private readonly IProtocolTemplateService _templateService; |
| | | private readonly ILogger<InstanceSyncService> _logger; |
| | | |
| | | private DateTime? _lastSyncTime; |
| | | |
| | | public DateTime? LastSyncTime => _lastSyncTime; |
| | | |
| | | public InstanceSyncService( |
| | | DatabaseDeviceService deviceService, |
| | | ISimulatorInstanceManager instanceManager, |
| | | IProtocolTemplateService templateService, |
| | | ILogger<InstanceSyncService> logger) |
| | | { |
| | | _deviceService = deviceService; |
| | | _instanceManager = instanceManager; |
| | | _templateService = templateService; |
| | | _logger = logger; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ§è¡åæ¥ï¼ä»æ°æ®åºè¯»å设å¤ï¼å建å®ä¾ååè®®æ¨¡æ¿ |
| | | /// </summary> |
| | | public async Task SyncInstancesAsync() |
| | | { |
| | | _logger.LogInformation("å¼å§åæ¥å®ä¾..."); |
| | | _lastSyncTime = DateTime.Now; |
| | | |
| | | // 1. è·åææ SiemensS7 è®¾å¤ |
| | | var devices = await _deviceService.GetSiemensS7DevicesAsync(); |
| | | if (devices.Count == 0) |
| | | { |
| | | _logger.LogWarning("æªæ¾å° SiemensS7 设å¤ï¼åæ¥åæ¶"); |
| | | return; |
| | | } |
| | | |
| | | // 2. è·åç°æå®ä¾IDå表 |
| | | var existingInstanceIds = _instanceManager.GetAllInstances().Select(i => i.Config.Id).ToHashSet(StringComparer.OrdinalIgnoreCase); |
| | | var dbDeviceCodes = devices.Select(d => d.DeviceCode).ToHashSet(StringComparer.OrdinalIgnoreCase); |
| | | |
| | | // 3. æ¸
çå·²ä¸åå¨çå®ä¾ï¼æ°æ®åºä¸æ²¡æä½å
åä¸æï¼ |
| | | foreach (var instanceId in existingInstanceIds) |
| | | { |
| | | if (!dbDeviceCodes.Contains(instanceId)) |
| | | { |
| | | _logger.LogInformation("æ°æ®åºä¸å·²å é¤è®¾å¤ {InstanceId}ï¼ä»å
åç§»é¤", instanceId); |
| | | await _instanceManager.DeleteInstanceAsync(instanceId, deleteConfig: false); |
| | | } |
| | | } |
| | | |
| | | // 4. åå»ºææ´æ°å®ä¾ |
| | | foreach (var device in devices) |
| | | { |
| | | try |
| | | { |
| | | // 4.1 è·å设å¤åè®® |
| | | var protocols = await _deviceService.GetDeviceProtocolsAsync(device.Id); |
| | | |
| | | // 4.2 å建åè®®æ¨¡æ¿ |
| | | var templateId = $"protocol-{device.DeviceCode}"; |
| | | var template = new ProtocolTemplate |
| | | { |
| | | Id = templateId, |
| | | Name = $"{device.DeviceName} å议模æ¿", |
| | | Version = "1.0", |
| | | Fields = protocols.Select(p => new ProtocolFieldMapping |
| | | { |
| | | FieldKey = p.DeviceProParamName, |
| | | DbNumber = int.TryParse(p.DeviceProDataBlock, out var dbNum) ? dbNum : 50, |
| | | Offset = (int)p.DeviceProOffset, |
| | | Bit = 1, |
| | | DataType = MapDataType(p.DeviceProDataType), |
| | | Length = p.DeviceProDataLength, |
| | | Direction = ProtocolFieldDirection.Bidirectional |
| | | }).ToList() |
| | | }; |
| | | await _templateService.UpsertAsync(template); |
| | | |
| | | // 4.3 å建å®ä¾é
ç½® |
| | | var config = new InstanceConfig |
| | | { |
| | | Id = device.DeviceCode, |
| | | Name = device.DeviceName, |
| | | PLCType = SiemensPLCType.S71500, // é»è®¤ S7-1500ï¼å¯æ ¹æ®éè¦æ©å± |
| | | Port = device.DevicePort, |
| | | AutoStart = false, |
| | | ProtocolTemplateId = templateId, |
| | | MemoryConfig = GetDefaultMemoryConfig() |
| | | }; |
| | | |
| | | // 4.4 åå»ºææ´æ°å®ä¾ |
| | | if (_instanceManager.InstanceExists(device.DeviceCode)) |
| | | { |
| | | _logger.LogInformation("å®ä¾ {DeviceCode} å·²åå¨ï¼è·³è¿å建", device.DeviceCode); |
| | | } |
| | | else |
| | | { |
| | | await _instanceManager.CreateInstanceAsync(config); |
| | | _logger.LogInformation("å·²å建å®ä¾ {DeviceCode} (端å£:{Port})", device.DeviceCode, device.DevicePort); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "åæ¥è®¾å¤ {DeviceCode} 失败", device.DeviceCode); |
| | | } |
| | | } |
| | | |
| | | _logger.LogInformation("忥宿"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ°æ®ç±»åæ å°ï¼æ°æ®åºå符串 -> ProtocolDataType æä¸¾ |
| | | /// ProtocolDataType: Byte=0, Int=1, DInt=2, String=3, Bool=4 |
| | | /// </summary> |
| | | private static ProtocolDataType MapDataType(string? dbDataType) |
| | | { |
| | | return dbDataType?.ToLowerInvariant() switch |
| | | { |
| | | "bit" => ProtocolDataType.Bool, // Bool=4 |
| | | "byte" => ProtocolDataType.Byte, // Byte=0 |
| | | "int" or "word" => ProtocolDataType.Int, // Int=1 |
| | | "dint" => ProtocolDataType.DInt, // DInt=2 |
| | | "string" or "string8" or "string16" => ProtocolDataType.String, // String=3 |
| | | _ => ProtocolDataType.Byte |
| | | }; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åé»è®¤å
åé
ç½® |
| | | /// </summary> |
| | | private static MemoryRegionConfig GetDefaultMemoryConfig() |
| | | { |
| | | return new MemoryRegionConfig |
| | | { |
| | | MRegionSize = 1024, |
| | | DBBlockCount = 1, |
| | | DBBlockNumbers = new List<int> { 50 }, |
| | | DBBlockSize = 65536, |
| | | IRegionSize = 256, |
| | | QRegionSize = 256, |
| | | TRegionCount = 64, |
| | | CRegionCount = 64 |
| | | }; |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Application/InstanceSyncService.cs |
| | | git commit -m "feat: æ·»å InstanceSyncService 忥åè°é»è¾" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 6: å建 SyncController |
| | | |
| | | **Files:** |
| | | - Create: `WIDESEAWCS_S7Simulator.Server/Controllers/SyncController.cs` |
| | | |
| | | - [ ] **Step 1: å建 SyncController.cs** |
| | | |
| | | ```csharp |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using WIDESEAWCS_S7Simulator.Application; |
| | | |
| | | namespace WIDESEAWCS_S7Simulator.Server.Controllers; |
| | | |
| | | [ApiController] |
| | | [Route("api/[controller]")] |
| | | public class SyncController : ControllerBase |
| | | { |
| | | private readonly InstanceSyncService _syncService; |
| | | private readonly ILogger<SyncController> _logger; |
| | | |
| | | public SyncController(InstanceSyncService syncService, ILogger<SyncController> logger) |
| | | { |
| | | _syncService = syncService; |
| | | _logger = logger; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æå¨è§¦åå®ä¾åæ¥ |
| | | /// </summary> |
| | | [HttpPost("SyncInstances")] |
| | | public async Task<IActionResult> SyncInstances() |
| | | { |
| | | try |
| | | { |
| | | _logger.LogInformation("æ¶å°æå¨åæ¥è¯·æ±"); |
| | | await _syncService.SyncInstancesAsync(); |
| | | return Ok(new { message = "忥宿", lastSyncTime = _syncService.LastSyncTime }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(ex, "æå¨åæ¥å¤±è´¥"); |
| | | return StatusCode(500, new { message = "åæ¥å¤±è´¥", error = ex.Message }); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·å䏿¬¡åæ¥æ¶é´ |
| | | /// </summary> |
| | | [HttpGet("LastSyncTime")] |
| | | public IActionResult GetLastSyncTime() |
| | | { |
| | | return Ok(new { lastSyncTime = _syncService.LastSyncTime }); |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Server/Controllers/SyncController.cs |
| | | git commit -m "feat: æ·»å SyncController API æ¥å£" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 7: ä¿®æ¹ appsettings.json æ·»å WcsDb é
ç½® |
| | | |
| | | **Files:** |
| | | - Modify: `WIDESEAWCS_S7Simulator.Server/appsettings.json` |
| | | |
| | | - [ ] **Step 1: æ·»å WcsDb é
ç½®è** |
| | | |
| | | å¨ appsettings.json æ ¹å¯¹è±¡æ·»å ï¼ |
| | | |
| | | ```json |
| | | "WcsDb": { |
| | | "Enabled": true, |
| | | "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=${WCS_DB_PASSWORD};Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", |
| | | "DbType": 2 |
| | | } |
| | | ``` |
| | | |
| | | 注æï¼`${WCS_DB_PASSWORD}` 为ç¯å¢åéå ä½ç¬¦ï¼å®é
é¨ç½²æ¶æ¿æ¢ä¸ºçå®å¯ç æéè¿ç¯å¢åéæ³¨å
¥ã |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Server/appsettings.json |
| | | git commit -m "feat: æ·»å WcsDb æ°æ®åºé
ç½®" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 8: ä¿®æ¹ Program.cs 注åæå¡åå¯å¨åæ¥ |
| | | |
| | | **Files:** |
| | | - Modify: `WIDESEAWCS_S7Simulator.Server/Program.cs` |
| | | |
| | | - [ ] **Step 1: 注åæå¡å¹¶å¯å¨æ¶åæ¥** |
| | | |
| | | å¨ `builder.Services.AddControllers()` ä¹åæ·»å ï¼ |
| | | |
| | | ```csharp |
| | | // WCS æ°æ®åºé
ç½® |
| | | builder.Services.Configure<WcsDbOptions>(builder.Configuration.GetSection(WcsDbOptions.SectionName)); |
| | | builder.Services.AddSingleton<DatabaseDeviceService>(); |
| | | builder.Services.AddSingleton<InstanceSyncService>(); |
| | | ``` |
| | | |
| | | å¨ `app.MapControllers()` ä¹åï¼å°åæ¥æ´åå°ç°æç `Task.Run` ä¸ï¼ |
| | | |
| | | ```csharp |
| | | // å¯å¨æ¶å 载已ä¿åçå®ä¾ï¼ä¸èªå¨å¯å¨ï¼ |
| | | var instanceManager = app.Services.GetRequiredService<ISimulatorInstanceManager>(); |
| | | var syncService = app.Services.GetRequiredService<InstanceSyncService>(); |
| | | _ = Task.Run(async () => |
| | | { |
| | | try |
| | | { |
| | | // å
å 载已ä¿åçå®ä¾ |
| | | await instanceManager.LoadSavedInstancesAsync(autoStart: false); |
| | | Console.WriteLine($"Loaded {instanceManager.GetAllInstances().Count()} saved instances."); |
| | | |
| | | // 妿å¯ç¨äº WCS æ°æ®åºåæ¥ï¼åæ§è¡åæ¥ |
| | | var wcsDbOptions = app.Services.GetRequiredService<IOptions<WcsDbOptions>>().Value; |
| | | if (wcsDbOptions.Enabled) |
| | | { |
| | | await syncService.SyncInstancesAsync(); |
| | | Console.WriteLine($"WCS DB sync completed. Last sync: {syncService.LastSyncTime}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"Error during startup: {ex.Message}"); |
| | | } |
| | | }); |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Commit** |
| | | |
| | | ```bash |
| | | git add WIDESEAWCS_S7Simulator.Server/Program.cs |
| | | git commit -m "feat: Program.cs 注å忥æå¡å¹¶å¯å¨æ¶åæ¥" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## Task 9: æå»ºéªè¯ |
| | | |
| | | - [ ] **Step 1: è¿è¡ dotnet build éªè¯ç¼è¯** |
| | | |
| | | ```bash |
| | | cd WIDESEAWCS_S7Simulator.Server |
| | | dotnet build |
| | | ``` |
| | | |
| | | é¢æï¼æ ç¼è¯é误 |
| | | |
| | | - [ ] **Step 2: Commit any last changes if needed** |
| | | |
| | | --- |
| | | |
| | | ## æ§è¡é¡ºåº |
| | | |
| | | 1. Task 1 - æ·»å SqlSugarCore ä¾èµ |
| | | 2. Task 2 - å建 WCS æ°æ®åº DTO |
| | | 3. Task 3 - å建 WcsDbOptions é
置类 |
| | | 4. Task 4 - å建 DatabaseDeviceService |
| | | 5. Task 5 - å建 InstanceSyncService |
| | | 6. Task 6 - å建 SyncController |
| | | 7. Task 7 - ä¿®æ¹ appsettings.json |
| | | 8. Task 8 - ä¿®æ¹ Program.cs |
| | | 9. Task 9 - æå»ºéªè¯ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # S7 模æå¨æ°æ®åºå®ä¾åæ¥è®¾è®¡ |
| | | |
| | | ## èæ¯ |
| | | |
| | | S7 模æå¨å½åéè¿æ¬å° JSON æä»¶æå¨é
ç½®å®ä¾åå议模æ¿ï¼å·¥ä½é大ä¸å®¹æåºéãWCS ç³»ç»å·²æå®æ´ç设å¤ä¿¡æ¯æ°æ®åºï¼SQL Serverï¼ï¼å
å« `Dt_DeviceInfo` å `Dt_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` æ·»å ï¼ |
| | | |
| | | ```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) | |
| | | |
| | | ## å®ä¾é
ç½®é»è®¤å¼ |
| | | |
| | | ```csharp |
| | | 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. 对æ¯ç°æå®ä¾ï¼ |
| | | - **æ°å¢ç**ï¼å建å®ä¾ + ä¿ååè®®æ¨¡æ¿ |
| | | - **å·²åå¨ç**ï¼æ´æ°å®ä¾é
ç½®ï¼å¯éï¼ |
| | | - **æ°æ®åºå·²å é¤ç**ï¼ä»å
åç§»é¤ï¼ä¿çæä»¶é
ç½® |
| | | 5. 忥åå®ä¾ç¶æé»è®¤ä¸º **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` - 注åæå¡ãå¯å¨æ¶åæ¥ |