From 308694af268ae335e366174a103527d29982ca9e Mon Sep 17 00:00:00 2001 From: sige Date: Fri, 22 Dec 2023 14:10:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...程(非最终稿)第二版 2023.5.15.xlsx | Bin 0 -> 14448 bytes .../boditech/controller/AccountController.java | 7 +- .../boditech/controller/DeviceController.java | 10 --- .../driver/consumable/CsmBufferTubeBox.java | 10 ++- .../driver/consumable/CsmBufferTubeManager.java | 59 +++++++-------- .../driver/consumable/CsmLargeBufferTube.java | 17 +++++ .../consumable/CsmLargeBufferTubeManager.java | 79 +++++++++++++++----- .../boditech/driver/consumable/CsmTestCardBox.java | 12 +-- .../driver/consumable/CsmTestCardManager.java | 12 +-- .../dreamworks/boditech/driver/task/TaskLoad.java | 82 ++++++++++++++++++--- .../com/dreamworks/boditech/entity/Project.java | 13 ++++ .../boditech/service/AccountService.java | 5 ++ .../boditech/service/ActionLogService.java | 5 ++ .../dreamworks/boditech/service/DeviceService.java | 3 + .../boditech/service/ProjectService.java | 32 +++++--- 15 files changed, 248 insertions(+), 98 deletions(-) create mode 100644 doc/A8000测试流程(非最终稿)第二版 2023.5.15.xlsx diff --git a/doc/A8000测试流程(非最终稿)第二版 2023.5.15.xlsx b/doc/A8000测试流程(非最终稿)第二版 2023.5.15.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b4d2a6b58d8d957492f2e882a4cac23f30f795d3 GIT binary patch literal 14448 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 barcode + * @param index - position of buffer tube in cell + * @param code - box code string */ public void appendByCode( Integer index, String code ) { - // @TODO : 由于缺少 code 格式,所以都做 "hsCRP" 项目处理 - String projectName = "hsCRP"; - Project project = this.device.projectService.findByName(projectName); - if ( null == project ) { - throw new RuntimeException("project not found"); + String lotCode = code.substring(2); + Integer projectCode = Integer.parseInt(code.substring(0, 2)); + Project project = this.device.projectService.activeProjectGetByCodeNum(projectCode, lotCode); + if (!Objects.equals(project.posIndex, index)) { + throw new RuntimeException("BUFFER_TUBE_PROJECT_NOT_MATCHED"); } - // remove all buffer tube A with matched zoneIndex - this.bufferTubeList.removeIf(bufferTubeA -> bufferTubeA.areaIndex.equals(index)); - - for ( int i=0; i<25; i++ ) { - // append new buffer tube A - CsmBufferTube bufferTube = new CsmBufferTube(this); - bufferTube.areaIndex = index; - bufferTube.position = i; - bufferTube.projectName = project.name; - // @TODO : 这里没法判断是那种盖子,所以都做 500μl 处理 - bufferTube.coverType = CsmBufferTube.COVER_TYPE_150; - this.bufferTubeList.add(bufferTube); - } + CsmBufferTubeBox box = this.bufferTubeBoxes.get(index); + box.projectName = project.name; + box.projectId = project.id; + box.projectColor = project.color; + box.tubeAmount = 25; + box.isLoaded = true; + box.status = CsmBufferTubeBox.STATUS_LOADED; } + + + + + + + + // list of buffer tube private final List bufferTubeList = new ArrayList<>(); diff --git a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTube.java b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTube.java index de9df7b..c5e3008 100644 --- a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTube.java +++ b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTube.java @@ -1,11 +1,28 @@ package com.dreamworks.boditech.driver.consumable; public class CsmLargeBufferTube { + // index of tube : 0 - 5 + public Integer index = -1; + // if the tube is loaded + public Boolean isLoaded = false; + + // position public Integer position = -1; + // project id + public Integer projectId = 0; // project name public String projectName = ""; + // project color + public String projectColor = ""; // amount public Integer amount; + + + public static final String STATUS_NOT_LOADED = "NOT_LOADED"; + public static final String STATUS_LOADED = "LOADED"; + // status + public String status = CsmLargeBufferTube.STATUS_NOT_LOADED; + // exists public Boolean exists = false; diff --git a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java index ac127e8..2649f30 100644 --- a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java +++ b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java @@ -4,6 +4,7 @@ import com.dreamworks.boditech.driver.entity.ParamLargeBufferTubeUpdate; import com.dreamworks.boditech.entity.Project; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class CsmLargeBufferTubeManager { // device instance private final Device device; @@ -13,13 +14,11 @@ public class CsmLargeBufferTubeManager { // constructor public CsmLargeBufferTubeManager(Device device) { this.device = device; - - //@TODO: demo 数据 for ( int i=0; i<6; i++ ) { CsmLargeBufferTube tube = new CsmLargeBufferTube(this); tube.position = i; - tube.amount = 15; - tube.projectName = "demo" + i; + tube.index = i; + tube.status = CsmLargeBufferTube.STATUS_NOT_LOADED; this.largeBufferTubes.add(tube); } } @@ -35,27 +34,67 @@ public class CsmLargeBufferTubeManager { } /** - * append large buffer tube by box code - * @param code box code string + * append large buffer tube by box code string + * code example : 01CAGGB66U + * code format : [projectCodeNum(2)][lotCode(8)] + * @link Generate barcode + * @param index - position of buffer tube in cell + * @param code - box code string */ - public void appendByCode( Integer position, String code ) { - // @TODO : code 格式暂无,所以都做 "hsCRP" 项目处理 - String projectName = "hsCRP"; - Project project = this.device.projectService.findByName(projectName); - if ( null == project ) { - throw new RuntimeException("project not found"); + public void appendByCode( Integer index, String code ) { + String lotCode = code.substring(2); + Integer projectCode = Integer.parseInt(code.substring(0, 2)); + Project project = this.device.projectService.activeProjectGetByCodeNum(projectCode, lotCode); + if (!Objects.equals(project.posIndex, index)) { + throw new RuntimeException("BUFFER_TUBE_PROJECT_NOT_MATCHED"); } - // remove all large buffer tubes with matched position - this.largeBufferTubes.removeIf(largeBufferTube -> largeBufferTube.position.equals(position)); - - // append new large buffer tubes - CsmLargeBufferTube largeBufferTube = new CsmLargeBufferTube(this); - largeBufferTube.position = position; - largeBufferTube.projectName = "hsCRP"; - this.largeBufferTubes.add(largeBufferTube); + CsmLargeBufferTube box = this.largeBufferTubes.get(index); + box.projectName = project.name; + box.projectId = project.id; + box.projectColor = project.color; + box.amount = 25; + box.isLoaded = true; + box.status = CsmLargeBufferTube.STATUS_LOADED; } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // get large buffer tube public CsmLargeBufferTube getTubeByProjectName( String projectName ) { CsmLargeBufferTube tube = null; diff --git a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardBox.java b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardBox.java index 0c9a8ec..5894bf6 100644 --- a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardBox.java +++ b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardBox.java @@ -1,12 +1,10 @@ package com.dreamworks.boditech.driver.consumable; public class CsmTestCardBox { - // status of test card box : OK - public static final String STATUS_OK = "OK"; - - /** - * index of test card box : 0 - 5 - */ + // index of test card box : 0 - 5 public Integer index = -1; + // if the test card box is loaded + public Boolean isLoaded = false; + public Integer projectId; public String projectName; @@ -15,6 +13,8 @@ public class CsmTestCardBox { public String lotCode; public Integer cardAmount = 0; + // status of test card box : OK + public static final String STATUS_OK = "OK"; /** * status of test card box : *
  • - OK diff --git a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardManager.java b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardManager.java index 24b2e5d..3b7f9a0 100644 --- a/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardManager.java +++ b/src/main/java/com/dreamworks/boditech/driver/consumable/CsmTestCardManager.java @@ -16,18 +16,9 @@ public class CsmTestCardManager { // constructor public CsmTestCardManager(Device device) { this.device = device; - - String[] colors = new String[]{"red", "green", "blue", "yellow", "purple", "orange"}; - for ( int i=0; i<6; i++ ) { CsmTestCardBox box = new CsmTestCardBox(); box.index = i; - - // @TODO : demo 数据 - box.projectName = "demo" + i; - box.projectId = 1; - box.projectColor = colors[i]; - this.testCardBoxes.add(box); } } @@ -76,12 +67,13 @@ public class CsmTestCardManager { } Integer projectCodeNum = Integer.parseInt(parts[0]); - Project project = this.device.projectService.activeProjectByCodeNum(projectCodeNum); + Project project = this.device.projectService.activeProjectByCodeNum(index, projectCodeNum, box.lotCode); box.projectId = project.id; box.projectName = project.name; box.projectColor = project.color; box.cardAmount = 25; box.status = CsmTestCardBox.STATUS_OK; + box.isLoaded = true; } diff --git a/src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java b/src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java index 61dfe97..195c679 100644 --- a/src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java +++ b/src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java @@ -5,16 +5,20 @@ import com.dreamworks.boditech.driver.actuator.ActCodeScanner; import com.dreamworks.boditech.driver.actuator.ActModuleTestCardBoxCase; import com.dreamworks.boditech.driver.actuator.ActuatorModule; public class TaskLoad extends TaskBase { + // arm xy + private ActArmXY armXY; + @Override public void execute(Executor executor) { Device device = executor.getDevice(); - ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); + this.armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); try { this.testCardLoad(executor); this.bufferTubeLoad(executor); + this.largeBufferTubeLoad(executor); } catch (RuntimeException e) { - armXY.reset(); + this.armXY.reset(); throw e; } } @@ -22,7 +26,16 @@ public class TaskLoad extends TaskBase { // load test card private void testCardLoad(Executor executor) { Device device = executor.getDevice(); - ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); + if ( !device.enable ) { // @TODO : 移除测试数据 + device.testCards.appendByBoxCode(0, "1||CAGGB66U||2024.03.26||1279||06"); + device.testCards.appendByBoxCode(1, "2||CAGGB66U||2024.03.26||1279||06"); + device.testCards.appendByBoxCode(2, "3||CAGGB66U||2024.03.26||1279||06"); + device.testCards.appendByBoxCode(3, "4||CAGGB66U||2024.03.26||1279||06"); + device.testCards.appendByBoxCode(4, "5||CAGGB66U||2024.03.26||1279||06"); + device.testCards.appendByBoxCode(5, "6||CAGGB66U||2024.03.26||1279||06"); + return ; + } + ActCodeScanner codeScanner = (ActCodeScanner)device.getActuator(ActuatorModule.ARM_Z_SCANNER); // 检查试卡盒仓盖是否关闭 @@ -35,7 +48,7 @@ public class TaskLoad extends TaskBase { Integer scanStartY = device.getLocationByName("testCardScanStart.y"); Integer scanDistance = device.getLocationByName("testCardBoxScanDistance"); for ( int i=0; i<6; i++ ) { - armXY.moveTo(scanStartX, scanStartY + i * scanDistance); + this.armXY.moveTo(scanStartX, scanStartY + i * scanDistance); String code = codeScanner.scan(500); if ( "".equals(code) ) { continue ; @@ -43,13 +56,22 @@ public class TaskLoad extends TaskBase { device.testCards.appendByBoxCode(i, code); } - armXY.reset(); + this.armXY.reset(); } // load buffer tube private void bufferTubeLoad(Executor executor) { Device device = executor.getDevice(); - ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); + if ( !device.enable ) { // @TODO : 移除测试数据 + device.bufferTubes.appendByCode(0, "01CAGGB66U"); + device.bufferTubes.appendByCode(1, "02CAGGB66U"); + device.bufferTubes.appendByCode(2, "03CAGGB66U"); + device.bufferTubes.appendByCode(3, "04CAGGB66U"); + device.bufferTubes.appendByCode(4, "05CAGGB66U"); + device.bufferTubes.appendByCode(5, "06CAGGB66U"); + return ; + } + ActCodeScanner codeScanner = (ActCodeScanner)device.getActuator(ActuatorModule.ARM_Z_SCANNER); Integer scanStartX = device.getLocationByName("bufferTubeLineOneScanStart.x"); @@ -57,7 +79,7 @@ public class TaskLoad extends TaskBase { // buffer tube line one for ( int i=0; i<3; i++ ) { - armXY.moveTo(scanStartX - i * 1200, scanStartY); + this.armXY.moveTo(scanStartX - i * 1200, scanStartY); String code = codeScanner.scan(500); if ( "".equals(code) ) { continue ; @@ -69,7 +91,7 @@ public class TaskLoad extends TaskBase { scanStartX = device.getLocationByName("bufferTubeLineTwoScanStart.x"); scanStartY = device.getLocationByName("bufferTubeLineTwoScanStart.y"); for ( int i=0; i<3; i++ ) { - armXY.moveTo(scanStartX - i * 1200, scanStartY); + this.armXY.moveTo(scanStartX - i * 1200, scanStartY); String code = codeScanner.scan(500); if ( "".equals(code) ) { continue ; @@ -77,6 +99,48 @@ public class TaskLoad extends TaskBase { device.bufferTubes.appendByCode(i+3, code); } - armXY.reset(); + this.armXY.reset(); + } + + // load large buffer tube + private void largeBufferTubeLoad(Executor executor) { + Device device = executor.getDevice(); + if ( !device.enable ) { // @TODO : 移除测试数据 + device.largeBufferTubes.appendByCode(0, "01CAGGB66U"); + device.largeBufferTubes.appendByCode(1, "02CAGGB66U"); + device.largeBufferTubes.appendByCode(2, "03CAGGB66U"); + device.largeBufferTubes.appendByCode(3, "04CAGGB66U"); + device.largeBufferTubes.appendByCode(4, "05CAGGB66U"); + device.largeBufferTubes.appendByCode(5, "06CAGGB66U"); + return ; + } + + ActCodeScanner codeScanner = (ActCodeScanner)device.getActuator(ActuatorModule.ARM_Z_SCANNER); + + Integer scanStartX = device.getLocationByName("largeBufferTubeRowOneScanStart.x"); + Integer scanStartY = device.getLocationByName("largeBufferTubeRowOneScanStart.y"); + + // row one + for ( int i=0; i<3; i++ ) { + this.armXY.moveTo(scanStartX - i * 300, scanStartY); + String code = codeScanner.scan(500); + if ( "".equals(code) ) { + continue ; + } + device.largeBufferTubes.appendByCode(i, code); + } + + // row two + scanStartY -= 600; + for ( int i=0; i<3; i++ ) { + this.armXY.moveTo(scanStartX - i * 300, scanStartY); + String code = codeScanner.scan(500); + if ( "".equals(code) ) { + continue ; + } + device.largeBufferTubes.appendByCode(i + 3, code); + } + + this.armXY.reset(); } } diff --git a/src/main/java/com/dreamworks/boditech/entity/Project.java b/src/main/java/com/dreamworks/boditech/entity/Project.java index 5e66beb..4294be4 100644 --- a/src/main/java/com/dreamworks/boditech/entity/Project.java +++ b/src/main/java/com/dreamworks/boditech/entity/Project.java @@ -7,4 +7,17 @@ public class Project { // color of project public String color; public String steps; + + /** + * position code in device, available values are 0, 1, 2, 3, 4, 5. + * this property would not be saved in database. + * @NOT-DATABASE-FIELD + */ + public Integer posIndex = 0; + + /** + * lot code of project + * @NOT-DATABASE-FIELD + */ + public String lotCode = ""; } diff --git a/src/main/java/com/dreamworks/boditech/service/AccountService.java b/src/main/java/com/dreamworks/boditech/service/AccountService.java index 17e2f51..34b107d 100644 --- a/src/main/java/com/dreamworks/boditech/service/AccountService.java +++ b/src/main/java/com/dreamworks/boditech/service/AccountService.java @@ -20,6 +20,11 @@ public class AccountService { // current user private Account curAccount = null; + // get current user + public Account getCurAccount() { + return this.curAccount; + } + // list-login-accounts public List listLoginAccounts(Integer limit) { return this.userMapper.listLoginAccounts(limit); diff --git a/src/main/java/com/dreamworks/boditech/service/ActionLogService.java b/src/main/java/com/dreamworks/boditech/service/ActionLogService.java index 3775ce9..e967530 100644 --- a/src/main/java/com/dreamworks/boditech/service/ActionLogService.java +++ b/src/main/java/com/dreamworks/boditech/service/ActionLogService.java @@ -2,6 +2,8 @@ package com.dreamworks.boditech.service; import com.dreamworks.boditech.entity.ActionLogEntry; import com.dreamworks.boditech.mapper.ActionLogMapper; import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @@ -10,6 +12,8 @@ import java.util.ArrayList; import java.util.List; @Service public class ActionLogService { + // logger + private static final Logger LOG = LoggerFactory.getLogger(ActionLogService.class); @Resource private ActionLogMapper actionLogMapper; // user id @@ -34,5 +38,6 @@ public class ActionLogService { entry.params = String.join(",", paramList); entry.startedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); this.actionLogMapper.insert(entry); + LOG.info("[User:{}#{}] {}", entry.userId, entry.action, entry.params); } } diff --git a/src/main/java/com/dreamworks/boditech/service/DeviceService.java b/src/main/java/com/dreamworks/boditech/service/DeviceService.java index 03d32c7..86349ca 100644 --- a/src/main/java/com/dreamworks/boditech/service/DeviceService.java +++ b/src/main/java/com/dreamworks/boditech/service/DeviceService.java @@ -16,6 +16,8 @@ public class DeviceService { public Device device; @Resource public RuntimeVariableService runtimeVariableService; + @Resource + private ActionLogService actionLog; // tasks private final List tasks = new ArrayList<>(); @@ -39,6 +41,7 @@ public class DeviceService { * load consumable resources */ public void load() { + this.actionLog.log("device.load"); TaskLoad task = new TaskLoad(); Executor.executeTask(this.device, task); } diff --git a/src/main/java/com/dreamworks/boditech/service/ProjectService.java b/src/main/java/com/dreamworks/boditech/service/ProjectService.java index 8799215..ec23596 100644 --- a/src/main/java/com/dreamworks/boditech/service/ProjectService.java +++ b/src/main/java/com/dreamworks/boditech/service/ProjectService.java @@ -14,30 +14,44 @@ public class ProjectService { private List projects; // project colors private final String[] colors = new String[]{"red", "green", "blue", "yellow", "orange", "pink"}; - // project color index - private Integer colorIndex = 0; @PostConstruct public void init() { this.projects = new ArrayList<>(); + for ( int i=0; i<6; i++ ) { + this.projects.add(null); + } } - // active project - public Project activeProjectByCodeNum(Integer codeNum) { + // get active project by given code num + public Project activeProjectGetByCodeNum( Integer codeNum, String lotCode ) { for ( Project project : this.projects ) { - if ( project.codeNum.equals(codeNum) ) { + if ( null != project + && project.codeNum.equals(codeNum) + && project.lotCode.equals(lotCode) + ) { return project; } } + throw new RuntimeException("PROJECT_CODE_NOT_ACTIVE"); + } + + // active project + public Project activeProjectByCodeNum(Integer posIndex, Integer codeNum, String lotCode) { + Project project = this.projects.get(posIndex); + if ( null != project ) { + throw new RuntimeException("PROJECT_CODE_ALREADY_ACTIVE"); + } - Project project = this.findByCodeNum(codeNum); + project = this.findByCodeNum(codeNum); if ( project == null ) { throw new RuntimeException("PROJECT_CODE_NOT_AVAILABLE"); } - project.color = this.colors[this.colorIndex % this.colors.length]; - this.projects.add(project); - this.colorIndex++; + project.posIndex = posIndex; + project.lotCode = lotCode; + project.color = this.colors[posIndex]; + this.projects.set(posIndex, project); return project; }