From 77410e1412ab9243821a2f51c1fe59e770c8ef87 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 31 Jul 2025 15:18:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=80=A5=E5=81=9C=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/app/assistant/ApiRetTestControler.java | 2 +- .../channel/A8kCanBusCommunicationChannel.java | 114 ++---- .../a8k/app/iflytophald/config/ActionCommands.java | 4 + .../iflytophald/driver/A8kCanBusBaseDriver.java | 161 +++++--- .../driver/WaterTemperatureControllerDriver.java | 14 +- .../a8k/app/iflytophald/info/CmdIdInfoMgr.java | 119 ++++++ .../type/protocol/A8kCmdAttachmentType.java | 7 + .../app/iflytophald/type/protocol/A8kPacket.java | 93 +---- .../a8k/app/iflytophald/type/protocol/CmdId.java | 411 ++++++++++----------- .../a8k/app/iflytophald/utils/PacketFormater.java | 73 ++++ .../mainctrl/AppConsumablesScanService.java | 24 +- .../service/mainctrl/MainFlowCtrlScheduler.java | 19 +- 12 files changed, 599 insertions(+), 442 deletions(-) create mode 100644 src/main/java/a8k/app/iflytophald/config/ActionCommands.java create mode 100644 src/main/java/a8k/app/iflytophald/info/CmdIdInfoMgr.java create mode 100644 src/main/java/a8k/app/iflytophald/type/protocol/A8kCmdAttachmentType.java create mode 100644 src/main/java/a8k/app/iflytophald/utils/PacketFormater.java diff --git a/src/main/java/a8k/app/controler/api/v1/app/assistant/ApiRetTestControler.java b/src/main/java/a8k/app/controler/api/v1/app/assistant/ApiRetTestControler.java index f569680..0db84f9 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/assistant/ApiRetTestControler.java +++ b/src/main/java/a8k/app/controler/api/v1/app/assistant/ApiRetTestControler.java @@ -29,7 +29,7 @@ public class ApiRetTestControler { @Operation(description = "获取硬件错误返回值,此类错误为底层发生的硬件错误") @PostMapping("getHardwareError") public ApiRet getAppHardwareError() throws AppException { - throw new AppException(new AEHardwareError(A8kEcode.APPE_PUT_TIP_FAIL, MId.PipetteModCodeScanner, CmdId.a8k_opt_v2_f_close_laster)); + throw new AppException(new AEHardwareError(A8kEcode.APPE_PUT_TIP_FAIL, MId.PipetteModCodeScanner, CmdId.a8k_opt_v2_f_close_laser)); } @Operation(description = "获取代码错误返回值,此类错误为代码逻辑错误") @PostMapping("getAppCodeError") diff --git a/src/main/java/a8k/app/iflytophald/channel/A8kCanBusCommunicationChannel.java b/src/main/java/a8k/app/iflytophald/channel/A8kCanBusCommunicationChannel.java index cd6357b..68ba0fb 100644 --- a/src/main/java/a8k/app/iflytophald/channel/A8kCanBusCommunicationChannel.java +++ b/src/main/java/a8k/app/iflytophald/channel/A8kCanBusCommunicationChannel.java @@ -2,6 +2,7 @@ package a8k.app.iflytophald.channel; import a8k.OS; +import a8k.app.iflytophald.info.CmdIdInfoMgr; import a8k.app.iflytophald.type.protocol.*; import a8k.app.type.appevent.A8kCanBusOnConnectEvent; import a8k.app.type.appevent.A8kHardwareReport; @@ -12,6 +13,7 @@ import a8k.app.service.background.AppEventBusService; import a8k.app.utils.ByteArrayUtils; import a8k.app.utils.ZList; import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.java_websocket.client.WebSocketClient; import org.java_websocket.enums.ReadyState; @@ -33,17 +35,6 @@ import java.util.concurrent.TimeUnit; @Slf4j public class A8kCanBusCommunicationChannel extends WebSocketClient { - @Resource - AppEventBusService eventBus; - - String datachurl = null; - String cmdchurl = null; - Boolean firstCall = true; - - @Value("${iflytophald.enable}") - Boolean iflytophaldEnable; - - static class ProcessContext { BlockingQueue receiptQueue = new LinkedBlockingQueue<>(); // A8kPacket cmdPacket; @@ -104,7 +95,7 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { synchronized void storageTxLastCmd(A8kPacket pack) { MId mid = MId.valueOf(pack.getModuleId()); CmdId cmdId = CmdId.valueOf(pack.getCmdId()); - if (cmdId != null && cmdId.isActionCmd()) + if (cmdId != null && CmdIdInfoMgr.isActionCmd(cmdId)) txcmdcache.put(mid, cmdId); } @@ -114,23 +105,31 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { } - ProcessContext context = new ProcessContext(); - int packetIndex = 0;//发送包的packetIndex + @Resource + AppEventBusService eventBus; + String dataChannelUrl = null; + String cmdChannelUrl = null; + Boolean firstCall = true; - public A8kCanBusCommunicationChannel(String cmdchurl, String datachurl) { - super(URI.create(datachurl)); - log.info("new A8kCanBusConnection: {} {}", cmdchurl, datachurl); + @Value("${iflytophald.enable}") + Boolean iflytophaldEnable; + + ProcessContext context = new ProcessContext(); + int packetIndex = 0;//发送包的packetIndex - this.datachurl = datachurl; - this.cmdchurl = cmdchurl; - packetIndex = 0; + public A8kCanBusCommunicationChannel(String cmdChannelUrl, String dataChannelUrl) { + super(URI.create(dataChannelUrl)); + log.info("new A8kCanBusConnection: {} {}", cmdChannelUrl, dataChannelUrl); + this.dataChannelUrl = dataChannelUrl; + this.cmdChannelUrl = cmdChannelUrl; + packetIndex = 0; } @Override public void onOpen(ServerHandshake serverHandshake) { - log.info("a8k canbus connect sucess"); + log.info("a8k canbus connect success"); eventBus.pushEvent(new A8kCanBusOnConnectEvent()); } @@ -148,35 +147,27 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { } - synchronized public A8kPacket callcmd(MId moduleId, CmdId cmdId, Integer... param) throws AppException { - var packet = packParamsToPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(param)); - return autoReSend(packet, A8kPacket.CMD_OVERTIME); - } - - synchronized public A8kPacket callcmd(MId moduleId, CmdId cmdId, Long overtime, Integer... params) throws AppException { - var packet = packParamsToPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(params)); - return autoReSend(packet, overtime); - } + // + // EXTERN + // synchronized public A8kPacket send(A8kPacket pack, int overtime) throws AppException { return priSend(pack, overtime); } - synchronized public ModuleStatus moduleGetStatus(MId id) throws AppException { - var getStatusPacket = packParamsToPacket(id.toInt(), CmdId.module_get_status.toInt(), ZList.of()); - for (int i = 0; i < 10; i++) { - try { - return ModuleStatus.valueOf(priSend(getStatusPacket, 30).getContentI32(0)); - } catch (AppException ignored) { - } - restartCanif(); - OS.hsleep(10); - } - throw AppException.of(new AEHardwareError(A8kEcode.LOW_ERROR_OVERTIME, - MId.valueOf(getStatusPacket.getModuleId()), CmdId.valueOf(getStatusPacket.getCmdId()))); + synchronized public A8kPacket autoReSend(A8kPacket pack, long overtime) throws AppException { + return priAutoReSend(pack, overtime); + } + + public synchronized CmdId getLastTxCmd(MId mid) { + return context.getLastTxCmd(mid); + } + public void restartCanif() { + callLocalCmd("restart"); } + // // PRIVATE // @@ -197,20 +188,13 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { } } - /** - * 强制关闭websocket连接,让其与canbus服务重连 - */ - private A8kPacket packParamsToPacket(Integer moduleId, Integer cmdId, List params) { - return A8kPacketFactory.buildCMDPacket(moduleId, cmdId, params); - } - - - private A8kPacket autoReSend(A8kPacket pack, long overtime) throws AppException { + private A8kPacket priAutoReSend(A8kPacket pack, long overtime) throws AppException { if (firstCall) { firstCall = false; restartCanif(); } + for (int j = 0; j < 2; j++) { for (int i = 0; i < 5; i++) { try { @@ -243,10 +227,6 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { } - AppException buildOvertimeError(A8kPacket pack) { - return AppException.of(new AEHardwareError(A8kEcode.LOW_ERROR_OVERTIME, MId.valueOf(pack.getModuleId()), CmdId.valueOf(pack.getCmdId()))); - } - private A8kPacket _priSend(A8kPacket pack, long overtime) throws AppException { // alloc new packetIndex packetIndex = packetIndex + 1; @@ -262,7 +242,7 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { // TX packet String txpacket = pack.toByteString(); log.debug("TX-RAW: {} | {}", txpacket, pack); - if(!isOpen()) { + if (!isOpen()) { try { connectBlocking(); } catch (InterruptedException e) { @@ -329,19 +309,16 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { } } - public synchronized CmdId getLastTxCmd(MId mid) { - return context.getLastTxCmd(mid); - } - public void restartCanif() { - callLocalCmd("restart"); + private AppException buildOvertimeError(A8kPacket pack) { + return AppException.of(new AEHardwareError(A8kEcode.LOW_ERROR_OVERTIME, MId.valueOf(pack.getModuleId()), CmdId.valueOf(pack.getCmdId()))); } - public HttpResponse callLocalCmd(String path) { + private HttpResponse callLocalCmd(String path) { // 创建一个HttpClient实例 HttpClient httpClient = HttpClient.newHttpClient(); - HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create(String.format("%s/%s", cmdchurl, path))).build(); + HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create(String.format("%s/%s", cmdChannelUrl, path))).build(); HttpResponse ret = null; try { ret = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); @@ -352,17 +329,6 @@ public class A8kCanBusCommunicationChannel extends WebSocketClient { return ret; } - public static void main(String[] args) { - HttpClient httpClient = HttpClient.newHttpClient(); - HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create("http://192.168.8.10:19004/zexcan/restart")).build(); - HttpResponse ret = null; - try { - ret = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - log.info("ret: \t{}", ret.body()); - } catch (Exception e) { - log.error("callcmd error", e); - } - } } diff --git a/src/main/java/a8k/app/iflytophald/config/ActionCommands.java b/src/main/java/a8k/app/iflytophald/config/ActionCommands.java new file mode 100644 index 0000000..ac5ab0d --- /dev/null +++ b/src/main/java/a8k/app/iflytophald/config/ActionCommands.java @@ -0,0 +1,4 @@ +package a8k.app.iflytophald.config; + +public class ActionCommands { +} diff --git a/src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java b/src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java index 6f4e17d..e9cdef9 100644 --- a/src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java +++ b/src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java @@ -3,6 +3,7 @@ package a8k.app.iflytophald.driver; import a8k.app.factory.A8kPacketFactory; import a8k.app.iflytophald.channel.A8kCanBusCommunicationChannel; +import a8k.app.iflytophald.info.CmdIdInfoMgr; import a8k.app.iflytophald.type.protocol.*; import a8k.app.type.error.AEHardwareError; import a8k.app.type.exception.AppException; @@ -35,7 +36,7 @@ public class A8kCanBusBaseDriver { boolean lockAction = false;//为true时,动作不可以被打断 } - private Map threadVars = new LinkedHashMap<>(); + private final Map threadVars = new LinkedHashMap<>(); private final Object threadVarsLock = new Object(); @PostConstruct @@ -61,25 +62,103 @@ public class A8kCanBusBaseDriver { // // BASE_OPERATION // - public A8kPacket callcmd(MId moduleId, CmdId cmdId, Integer... param) throws AppException { - return connection.callcmd(moduleId, cmdId, param); + //拦截指令 + if (emergencyKeyState && !isActionLocked() && CmdIdInfoMgr.isActionCmd(cmdId)) { + throw AppException.of(A8kEcode.EMERGENCY_KEY_TRIGGER); + } + + var packet = A8kPacketFactory.buildCMDPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(param)); + return connection.autoReSend(packet, A8kPacket.CMD_OVERTIME); } public A8kPacket callcmd(MId moduleId, CmdId cmdId, Long overtime, Integer... params) throws AppException { - return connection.callcmd(moduleId, cmdId, overtime, params); + //拦截指令 + if (emergencyKeyState && !isActionLocked() && CmdIdInfoMgr.isActionCmd(cmdId)) { + throw AppException.of(A8kEcode.EMERGENCY_KEY_TRIGGER); + } + var packet = A8kPacketFactory.buildCMDPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(params)); + return connection.autoReSend(packet, overtime); } - synchronized public A8kPacket send(A8kPacket pack, int overtime) throws AppException { + + public A8kPacket send(A8kPacket pack, int overtime) throws AppException { + //拦截指令 + if (emergencyKeyState && !isActionLocked() && CmdIdInfoMgr.isActionCmd(pack.getCmdId())) { + throw AppException.of(A8kEcode.EMERGENCY_KEY_TRIGGER); + } return connection.send(pack, overtime); } + public void restartCanif() { + connection.restartCanif(); + } + + public CmdId getLastTxCmd(MId mid) { + return connection.getLastTxCmd(mid); + } + + // + // 功能性接口 + // + + /** + * 同步急停按键状态 + * @param state 急停按键状态, true表示急停按键被按下, false表示急停按键未被按下 + */ + public void syncEmergencyKeyState(boolean state) { + emergencyKeyState = state; + } + + /** + * 锁定动作 + * 锁定后当前线程中执行的动作将不会被急停按键打断 + */ + public void lockAction() { + synchronized (threadVarsLock) { + ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); + if (threadVar == null) { + threadVar = new ThreadVar(); + threadVars.put(Thread.currentThread().threadId(), threadVar); + } + threadVar.lockAction = true; + } + } + + /** + * 解锁动作 + * @throws AppException 如果急停按键被按下, 则抛出异常 + */ + public void unlockAction() throws AppException { + synchronized (threadVarsLock) { + ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); + if (threadVar != null) { + threadVar.lockAction = false; + } + } + if (emergencyKeyState) { + throw AppException.of(A8kEcode.EMERGENCY_KEY_TRIGGER); + } + } + + /** + * 检查当前线程是否锁定了动作 + * @return + */ + public boolean isActionLocked() { + synchronized (threadVarsLock) { + ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); + return threadVar != null && threadVar.lockAction; + } + } + + // // MODULE FUNCTION // public void moduleStop(MId id) throws AppException { - connection.callcmd(id, CmdId.module_stop); + callcmd(id, CmdId.module_stop); } public void moduleStopNoException(MId id) { @@ -90,33 +169,49 @@ public class A8kCanBusBaseDriver { } public ModuleStatus moduleGetStatus(MId id) throws AppException { - return connection.moduleGetStatus(id); + var getStatusPacket = A8kPacketFactory.buildCMDPacket(id.toInt(), CmdId.module_get_status.toInt(), ZList.of()); + for (int i = 0; i < 30; i++) { + try { + int status = send(getStatusPacket, 30).getContentI32(0); + return ModuleStatus.valueOf(status); + } catch (AppException ignored) { + // moduleGetStatus 属于快速频发指令,所以如果发送失败,不报错 + } + if (i % 5 == 0) { + restartCanif(); + } + OS.hsleep(10); + } + throw AppException.of(new AEHardwareError(A8kEcode.LOW_ERROR_OVERTIME, + MId.valueOf(getStatusPacket.getModuleId()), CmdId.valueOf(getStatusPacket.getCmdId()))); + } + public void moduleSetReg(MId id, RegIndex regindex, Integer reg) throws AppException { - connection.callcmd(id, CmdId.module_set_reg, 100L, regindex.index, reg); + callcmd(id, CmdId.module_set_reg, 100L, regindex.index, reg); } public Integer moduleGetReg(MId id, RegIndex regindex) throws AppException { - var packet = connection.callcmd(id, CmdId.module_get_reg, 100L, regindex.index); + var packet = callcmd(id, CmdId.module_get_reg, 100L, regindex.index); return packet.getContentI32(0); } public A8kEcode moduleGetError(MId id) throws AppException { - var packet = connection.callcmd(id, CmdId.module_get_error); + var packet = callcmd(id, CmdId.module_get_error); return A8kEcode.fromInt(packet.getContentI32(0)); } public Integer moduleGetDetailError(MId id) throws AppException { - return connection.callcmd(id, CmdId.module_get_detail_error).getContentI32(0); + return callcmd(id, CmdId.module_get_detail_error).getContentI32(0); } public Integer moduleReadVersion(MId id) throws AppException { - return connection.callcmd(id, CmdId.module_get_version).getContentI32(0); + return callcmd(id, CmdId.module_get_version).getContentI32(0); } public ModuleType moduleReadType(MId id) throws AppException { - var packet = connection.callcmd(id, CmdId.module_get_type); + var packet = callcmd(id, CmdId.module_get_type); return ModuleType.of(packet.getContentI32(0)); } @@ -124,7 +219,7 @@ public class A8kCanBusBaseDriver { int i = 0; byte[] result = new byte[0]; while (true) { - var rxPacket = connection.callcmd(MId.A8kIdCardReader, CmdId.a8000_idcard_reader_read_raw, i++); + var rxPacket = callcmd(MId.A8kIdCardReader, CmdId.a8000_idcard_reader_read_raw, i++); if (rxPacket.getCmdContent().length == 0) { break; } @@ -133,44 +228,10 @@ public class A8kCanBusBaseDriver { return result; } - public void syncEmergencyKeyState(boolean state) { - emergencyKeyState = state; - } - - public void lockAction() { - synchronized (threadVarsLock) { - ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); - if (threadVar == null) { - threadVar = new ThreadVar(); - threadVars.put(Thread.currentThread().threadId(), threadVar); - } - threadVar.lockAction = true; - } - } - - public void unlockAction() throws AppException { - synchronized (threadVarsLock) { - ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); - if (threadVar != null) { - threadVar.lockAction = false; - } - } - if (emergencyKeyState) { - throw AppException.of(A8kEcode.EMERGENCY_KEY_TRIGGER); - } - } - - public boolean isActionLocked() { - synchronized (threadVarsLock) { - ThreadVar threadVar = threadVars.get(Thread.currentThread().threadId()); - return threadVar != null && threadVar.lockAction; - } - } - public void waitForMod(MId mid, Integer actionOvertime) throws AppException { long startedAt = OS.getMonotonicClockTimestamp(); - CmdId action = connection.getLastTxCmd(mid); + CmdId action = getLastTxCmd(mid); do { ModuleStatus statue = moduleGetStatus(mid); if (statue == ModuleStatus.IDLE) { @@ -197,7 +258,7 @@ public class A8kCanBusBaseDriver { } - void waitingForOptFinish() throws AppException { + public void waitingForOptFinish() throws AppException { long startedAt = OS.getMonotonicClockTimestamp(); do { diff --git a/src/main/java/a8k/app/iflytophald/driver/WaterTemperatureControllerDriver.java b/src/main/java/a8k/app/iflytophald/driver/WaterTemperatureControllerDriver.java index 49b4655..0d5481f 100644 --- a/src/main/java/a8k/app/iflytophald/driver/WaterTemperatureControllerDriver.java +++ b/src/main/java/a8k/app/iflytophald/driver/WaterTemperatureControllerDriver.java @@ -21,11 +21,11 @@ public class WaterTemperatureControllerDriver { public void startHearting(TemperatureControlerMid mid, Double temp) throws AppException { Integer tempInt = (int) ((temp) * 10); log.info("startHearting {} {}", mid, tempInt); - canBus.callcmd(mid.mid, CmdId.temp_controler_start_hearting, tempInt); + canBus.callcmd(mid.mid, CmdId.temp_controller_start_hearting, tempInt); } public void stopHearting(TemperatureControlerMid mid) throws AppException { - canBus.callcmd(mid.mid, CmdId.temp_controler_stop_hearting); + canBus.callcmd(mid.mid, CmdId.temp_controller_stop_hearting); } @@ -37,23 +37,23 @@ public class WaterTemperatureControllerDriver { public void startCtrlTemperature(TemperatureControlerMid mid, Double temperature) throws AppException { Integer setTemp = (int) ((temperature) * 10); - canBus.callcmd(mid.mid, CmdId.temp_controler_start_hearting, setTemp); + canBus.callcmd(mid.mid, CmdId.temp_controller_start_hearting, setTemp); } public void stopCtrlTemperature(TemperatureControlerMid mid) throws AppException { - canBus.callcmd(mid.mid, CmdId.temp_controler_stop_hearting); + canBus.callcmd(mid.mid, CmdId.temp_controller_stop_hearting); } public void setPeltierPower(TemperatureControlerMid mid, Integer val0To100) throws AppException { - canBus.callcmd(mid.mid, CmdId.temp_controler_set_peltier_power_level, val0To100); + canBus.callcmd(mid.mid, CmdId.temp_controller_set_peltier_power_level, val0To100); } public void setCtrlFanLevel(TemperatureControlerMid mid, Integer val0To100) throws AppException { - canBus.callcmd(mid.mid, CmdId.temp_controler_set_fan_level, val0To100); + canBus.callcmd(mid.mid, CmdId.temp_controller_set_fan_level, val0To100); } public void setWaterPumpSpeed(TemperatureControlerMid mid, Integer val0To100) throws AppException { - canBus.callcmd(mid.mid, CmdId.temp_controler_set_pump_level, val0To100); + canBus.callcmd(mid.mid, CmdId.temp_controller_set_pump_level, val0To100); } public Double readFeedbackTemperature(TemperatureControlerMid mid) throws AppException { diff --git a/src/main/java/a8k/app/iflytophald/info/CmdIdInfoMgr.java b/src/main/java/a8k/app/iflytophald/info/CmdIdInfoMgr.java new file mode 100644 index 0000000..0ebe08f --- /dev/null +++ b/src/main/java/a8k/app/iflytophald/info/CmdIdInfoMgr.java @@ -0,0 +1,119 @@ +package a8k.app.iflytophald.info; + +import a8k.app.iflytophald.type.protocol.A8kCmdAttachmentType; +import a8k.app.iflytophald.type.protocol.CmdId; + +import java.util.Objects; + +public class CmdIdInfoMgr { + + static public A8kCmdAttachmentType getCmdAttachType(CmdId cmdId) { + if (isCmdIdEq(cmdId, + CmdId.a8000_idcard_write_raw + )) { + return A8kCmdAttachmentType.BYTES; + } else { + return A8kCmdAttachmentType.INT32S; + } + } + + static public A8kCmdAttachmentType getReceiptAttachType(CmdId cmdId) { + if (isCmdIdEq(cmdId, + CmdId.a8k_opt_v2_read_raw, + CmdId.a8000_idcard_reader_read_raw + )) { + return A8kCmdAttachmentType.BYTES; + } else { + return A8kCmdAttachmentType.INT32S; + } + } + + + private static boolean isCmdIdEq(CmdId a, CmdId... b) { + for (CmdId cmdId : b) { + if (Objects.equals(a, cmdId)) { + return true; + } + } + return false; + } + + /** + * 判断是否是动作命令 + *

+ * 动作命令是指移动的命令, 例如XY电机移动, 步进电机移动等 + * + * @param cmdId 命令ID + * @return 是否是动作命令 + */ + static public boolean isActionCmd(CmdId cmdId) { + if (isCmdIdEq(cmdId, + CmdId.xymotor_move_by, + CmdId.xymotor_move_to, + CmdId.xymotor_move_to_zero, + CmdId.xymotor_motor_move_by_direct, + + CmdId.a8k_opt_v2_t_start_scan, + CmdId.a8k_opt_v2_f_start_scan, + + + CmdId.step_motor_easy_rotate, + CmdId.step_motor_easy_move_by, + CmdId.step_motor_easy_move_to, + CmdId.step_motor_easy_move_to_zero, + CmdId.step_motor_easy_set_current_pos, + CmdId.step_motor_easy_move_to_io, + CmdId.step_motor_move_by, + CmdId.step_motor_move_to, + CmdId.step_motor_move_to_zero_point_quick, + CmdId.step_motor_rotate, + CmdId.step_motor_easy_move_to_end_point, + CmdId.step_motor_easy_move_to_zero_point_quick, + CmdId.step_motor_easy_reciprocating_motion, + + CmdId.mini_servo_move_to, + CmdId.mini_servo_rotate, + CmdId.mini_servo_rotate_with_torque, + + CmdId.code_scaner_start_scan, + + CmdId.pipette_zmotor_move_zero, + CmdId.pipette_zmotor_move_to_zero_point_quick, + CmdId.pipette_zmotor_measure_distance, + CmdId.pipette_zmotor_move_by, + CmdId.pipette_zmotor_move_to, + CmdId.pipette_zmotor_move_to_tip_deposit, + CmdId.pipette_pump_init_device, + CmdId.pipette_pump_take_tip, + CmdId.pipette_pump_deposit_tip, + CmdId.pipette_pump_pierce_through, + CmdId.pipette_pump_aspirate_set_param, + CmdId.pipette_pump_aspirate, + CmdId.pipette_pump_putbak_tip, + CmdId.pipette_pump_distribu_all, + CmdId.pipette_test_pump_move_to_x100nl, + CmdId.pipette_test_lld, + CmdId.pipette_test_move_to_container_bottom, + CmdId.pipette_test_move_to_container_bottom_section_begin, + CmdId.pipette_test_move_to_immersion_pos, + CmdId.pipette_test_move_to_leaving_height_pos, + CmdId.pipette_test_move_to_jet_pos, + CmdId.pipette_test_move_to_lld_start_search_pos, + CmdId.pipette_test_move_to_fix_water_level_pos, + CmdId.pipette_test_move_to_pierce_pos, + CmdId.pipette_test_move_to_lld_end_pos + )) { + return true; + } else { + return false; + } + } + + static public boolean isActionCmd(int cmdId) { + CmdId cmd = CmdId.valueOf(cmdId); + if (cmd == null) { + return false; + } + return isActionCmd(cmd); + } +} diff --git a/src/main/java/a8k/app/iflytophald/type/protocol/A8kCmdAttachmentType.java b/src/main/java/a8k/app/iflytophald/type/protocol/A8kCmdAttachmentType.java new file mode 100644 index 0000000..a7c28a4 --- /dev/null +++ b/src/main/java/a8k/app/iflytophald/type/protocol/A8kCmdAttachmentType.java @@ -0,0 +1,7 @@ +package a8k.app.iflytophald.type.protocol; + +public enum A8kCmdAttachmentType { + BYTES, //byte数组 + INT16S, //int16数组 + INT32S //int32数组 +} diff --git a/src/main/java/a8k/app/iflytophald/type/protocol/A8kPacket.java b/src/main/java/a8k/app/iflytophald/type/protocol/A8kPacket.java index bb62121..ea2bb36 100644 --- a/src/main/java/a8k/app/iflytophald/type/protocol/A8kPacket.java +++ b/src/main/java/a8k/app/iflytophald/type/protocol/A8kPacket.java @@ -1,5 +1,6 @@ package a8k.app.iflytophald.type.protocol; +import a8k.app.iflytophald.utils.PacketFormater; import a8k.app.utils.ByteArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,32 +10,10 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; public class A8kPacket { - - //#pragma pack(push, 1) - //typedef struct { - // uint8_t packetType; - // uint16_t cmdid; - // uint8_t moduleId; - // uint16_t index; - // uint8_t datalen; - // uint8_t data[]; - // /* int8_t checksum;*/ - //} zcr_cmd_header_t; - // - //#pragma pack(pop) - //typedef enum { - // kptv2_cmd = 0xA0, - // kptv2_ack = 0xA1, - // kptv2_error_ack = 0xA2, - // kptv2_event = 0xA3, - //} zcan_cmd_packet_type_t; - // - /** - * * @WARNING * 1. 修改这里时,需要注意连同createPacket一起修改 - * 2. PACKET_MIN_LEN 比Header多一个字节,是因为还有一个字节的校验位 + * 2. PACKET_MIN_LEN 比Header多一个字节,是因为还有一个字节的校验位 */ public static final int PACKET_TYPE_OFFSET = 0; @@ -94,9 +73,9 @@ public class A8kPacket { if (raw.length < PACKET_MIN_LEN) { return new byte[0]; } - byte[] cmdcontent = new byte[getDataLen()]; - System.arraycopy(raw, DATA_OFFSET, cmdcontent, 0, getDataLen()); - return cmdcontent; + byte[] cmdContent = new byte[getDataLen()]; + System.arraycopy(raw, DATA_OFFSET, cmdContent, 0, getDataLen()); + return cmdContent; } public int[] getContentI16Array() { @@ -128,68 +107,10 @@ public class A8kPacket { return ByteArrayUtils.toByteString(raw); } - public String toString() { - int packetType = getPacketType(); - String ret = ""; - - CmdId cmdId = CmdId.valueOf(getCmdId()); - Assert.isTrue(cmdId != null, "cmdId is null"); - if (packetType == PACKET_TYPE_CMD) { - - if (cmdId.equals(CmdId.module_get_reg) || cmdId.equals(CmdId.module_set_reg)) { - RegIndex regIndex = RegIndex.valueOf(getContentI32(0)); - if (regIndex != null) { - ret = String.format("[CMD ] index:[%d] %s %s %s(%d) %d", getPacketIndex(), cmdId, - MId.valueOf(getModuleId()), regIndex, regIndex.index, getContentI32(1)); - } else { - ret = String.format("[CMD ] index:[%d] %s unkown_index(%d) %d", getPacketIndex(), cmdId, - getContentI32(0), getContentI32(1)); - } - } else { - if (cmdId.getCmdAttachType() == CmdId.ATTACH_IS_INT32) { - ret = String.format("[CMD ] index:[%d] (%s %s(%d) :param:[%s])", getPacketIndex(), cmdId, - MId.valueOf(getModuleId()), getModuleId(), formatInt32ATTACH(getCmdContent())); - } else { - ret = String.format("[CMD ] index:[%d] (%s %s(%d) :param:[%s])", getPacketIndex(), cmdId, - MId.valueOf(getModuleId()), getModuleId(), ByteArrayUtils.toByteString(getCmdContent())); - } - } - - } else if (packetType == PACKET_TYPE_ACK) { - if (cmdId.getReceiptAttachType() == CmdId.ATTACH_IS_INT32) { - ret = String.format("[ACK ] index:[%d] (%s :[%s])", getPacketIndex(), cmdId, - formatInt32ATTACH(getCmdContent())); - } else { - ret = String.format("[ACK ] index:[%d] (%s :[%s])", getPacketIndex(), cmdId, - ByteArrayUtils.toByteString(getCmdContent())); - } - } else if (packetType == PACKET_TYPE_ERROR_ACK) { - ret = String.format("[EACK ] index:[%d] (%s :[%s])", getPacketIndex(), cmdId, (getContentI32(0))); - } else if (packetType == PACKET_TYPE_EVENT) { - if (cmdId.getCmdAttachType() == CmdId.ATTACH_IS_INT32) { - ret = String.format("[EVENT] index:[%d] (%s %s(%d) :[%s])", getPacketIndex(), cmdId, - MId.valueOf(getModuleId()), getModuleId(), formatInt32ATTACH(getCmdContent())); - } else { - ret = String.format("[EVENT] index:[%d] (%s %s(%d) :[%s])", getPacketIndex(), cmdId, - MId.valueOf(getModuleId()), getModuleId(), ByteArrayUtils.toByteString(getCmdContent())); - } - } else { - ret = String.format("Unknown packet type: %d", packetType); - } - return ret; + @Override public String toString() { + return PacketFormater.packetToString(this); } - private String formatInt32ATTACH(byte[] attach) { - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < attach.length; i += 4) { - if (i + 3 >= attach.length) - break; - if (i != 0) - ret.append(","); - ret.append(String.format("%d", ByteArrayUtils.read32bit(attach, i))); - } - return ret.toString(); - } public Boolean isSupportPacket() { CmdId cmdid = CmdId.valueOf(getCmdId()); diff --git a/src/main/java/a8k/app/iflytophald/type/protocol/CmdId.java b/src/main/java/a8k/app/iflytophald/type/protocol/CmdId.java index 86a0cf6..7c04132 100644 --- a/src/main/java/a8k/app/iflytophald/type/protocol/CmdId.java +++ b/src/main/java/a8k/app/iflytophald/type/protocol/CmdId.java @@ -1,213 +1,223 @@ package a8k.app.iflytophald.type.protocol; +/** + * + * 添加新指令时 + * 需要根据指令的特点在CmdIdInfo中进行相应的配置 + */ public enum CmdId { - NotSet(0xFFFF, "NOACTION"),// + NotSet(0xFFFF, "NotSet"),// board_reset(0x0000, "复位板子"),// event_bus_reg_change_report(0x0064, "寄存器修改事件"),// // + module_ping(0x0101, "PING"), + module_stop(0x0102, "模块停止"), - module_ping(0x0101, "MODULE_PING"), - module_stop(0x0102, "MODULE_STOP"), + module_get_error(0x0110, "读取错误"), + module_get_detail_error(0x0111, "读取详细错误"), + module_clear_error(0x0112, "清除错误"), - module_get_error(0x0110, "MODULE_GET_ERROR"), - module_get_detail_error(0x0111, "MODULE_GET_DETAIL_ERROR"), - module_clear_error(0x0112, "MODULE_CLEAR_ERROR"), + module_set_reg(0x0120, "设置寄存器"), + module_get_reg(0x0121, "读取寄存器"), + module_reset_reg(0x0123, "复位寄存器"), - module_set_reg(0x0120, "MODULE_SET_REG"), - module_get_reg(0x0121, "MODULE_GET_REG"), - module_reset_reg(0x0123, "MODULE_RESET_REG"), + module_get_version(0x0130, "读取版本信息"), + module_get_type(0x0131, "读取模块类型"), + module_get_status(0x0132, "读取模块状态"), - module_get_version(0x0130, "MODULE_GET_VERSION"), - module_get_type(0x0131, "MODULE_GET_TYPE"), - module_get_status(0x0132, "MODULE_GET_STATUS"), - - // module_active_cfg(0x0110, "激活配置"),// // - xymotor_enable(0x0301, "XYMOTOR_ENABLE"),// - xymotor_move_by(0x0302, "XYMOTOR_MOVE_BY"),// - xymotor_move_to(0x0303, "XYMOTOR_MOVE_TO"),// - xymotor_move_to_zero(0x0304, "XYMOTOR_MOVE_TO_ZERO"),// - xymotor_read_pos(0x0306, "XYMOTOR_READ_POS"),// - xymotor_read_inio_index_in_stm32(0x0307, "XYMOTOR_READ_INIO_INDEX_IN_STM32"),// - xymotor_read_inio(0x0308, "XYMOTOR_READ_INIO"),// - xymotor_set_pos(0x0309, "XYMOTOR_SET_POS"),// - xymotor_motor_move_by_direct(0x030a, "XYMOTOR_MOTOR_MOVE_BY_DIRECT"),// - xymotor_read_enc_direct(0x030b, "XYMOTOR_READ_ENC_DIRECT"),// + // HBOT + // + xymotor_enable(0x0301, "HBOT使能"),// + xymotor_move_by(0x0302, "HBOT相对移动"),// + xymotor_move_to(0x0303, "HBOT绝对移动"),// + xymotor_move_to_zero(0x0304, "HBOT归零"),// + xymotor_read_pos(0x0306, "HBOT读取位置"),// + xymotor_read_inio_index_in_stm32(0x0307, "HBOT读取IO编号(STM32版本)"),// + xymotor_read_inio(0x0308, "HBOT读取IO编号"),// + xymotor_set_pos(0x0309, "HBOT设置位置"),// + xymotor_motor_move_by_direct(0x030a, "HBOT步进直控"),// + xymotor_read_enc_direct(0x030b, "HBOT直接读取编码器信息"),// + // - a8k_opt_v2_read_raw(0x0609, "A8K_OPT_V2_READ_RAW"),// + // OPT // - a8k_opt_v2_t_start_scan(0x0700, "A8K_OPT_V2_T_START_SCAN"),// - a8k_opt_v2_f_start_scan(0x0701, "A8K_OPT_V2_F_START_SCAN"),// - a8k_opt_v2_t_open_laster(0x070a, "A8K_OPT_V2_T_OPEN_LASTER"),// - a8k_opt_v2_t_close_laster(0x070b, "A8K_OPT_V2_T_CLOSE_LASTER"),// - a8k_opt_v2_t_readVal(0x070c, "A8K_OPT_V2_T_READVAL"),// - a8k_opt_v2_f_open_laster(0x070d, "A8K_OPT_V2_F_OPEN_LASTER"),// - a8k_opt_v2_f_close_laster(0x070e, "A8K_OPT_V2_F_CLOSE_LASTER"),// - a8k_opt_v2_f_readVal(0x070f, "A8K_OPT_V2_F_READVAL"),// + + a8k_opt_v2_read_raw(0x0609, "光学读取数据"),// // - step_motor_enable(0x0201, "STEP_MOTOR_ENABLE"),// - step_motor_read_pos(0x020b, "STEP_MOTOR_READ_POS"),// - step_motor_read_enc_pos(0x020c, "STEP_MOTOR_READ_ENC_POS"),// - step_motor_easy_rotate(0x0211, "STEP_MOTOR_EASY_ROTATE"),// - step_motor_easy_move_by(0x0212, "STEP_MOTOR_EASY_MOVE_BY"),// - step_motor_easy_move_to(0x0213, "STEP_MOTOR_EASY_MOVE_TO"),// - step_motor_easy_move_to_zero(0x0214, "STEP_MOTOR_EASY_MOVE_TO_ZERO"),// - step_motor_easy_set_current_pos(0x0215, "STEP_MOTOR_EASY_SET_CURRENT_POS"),// - step_motor_easy_move_to_io(0x0216, "STEP_MOTOR_EASY_MOVE_TO_IO"),// - step_motor_stop(0x0228, "STEP_MOTOR_STOP"),// - step_motor_move_by(0x021d, "STEP_MOTOR_MOVE_BY"), // (dpos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) - step_motor_move_to(0x021e, "STEP_MOTOR_MOVE_TO"), // (pos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) - step_motor_move_to_zero_point_quick(0x021f, "STEP_MOTOR_MOVE_TO_ZERO_POINT_QUICK"), // (speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) - step_motor_rotate(0x0220, "STEP_MOTOR_ROTATE"), // + a8k_opt_v2_t_start_scan(0x0700, "T光学开始扫描"),// + a8k_opt_v2_f_start_scan(0x0701, "F光学开始扫描"),// + a8k_opt_v2_t_open_laser(0x070a, "T光学打开激光(调试)"),// + a8k_opt_v2_t_close_laser(0x070b, "T光学关闭激光(调试)"),// + a8k_opt_v2_t_readVal(0x070c, "T光学读取反馈数值"),// + a8k_opt_v2_f_open_laser(0x070d, "F光学打开激光"),// + a8k_opt_v2_f_close_laser(0x070e, "F光学关闭激光"),// + a8k_opt_v2_f_readVal(0x070f, "F光学读取数值"),// + - step_motor_active_cfg(0x0229, "STEP_MOTOR_ACTIVE_CFG"),// - step_motor_read_io_state(0x022a, "STEP_MOTOR_READ_IO_STATE"),// - step_motor_easy_move_to_end_point(0x022c, "STEP_MOTOR_EASY_MOVE_TO_END_POINT"),// - step_motor_read_tmc5130_status(0x0232, "STEP_MOTOR_READ_TMC5130_STATUS"),// - step_motor_read_tmc5130_state(0x0233, "STEP_MOTOR_READ_TMC5130_STATE"),// - step_motor_read_io_index_in_stm32(0x0238, "STEP_MOTOR_READ_IO_INDEX_IN_STM32"),// - step_motor_set_subdevice_reg(0x0239, "STEP_MOTOR_SET_SUBDEVICE_REG"),// - step_motor_get_subdevice_reg(0x023a, "STEP_MOTOR_GET_SUBDEVICE_REG"),// - step_motor_easy_reciprocating_motion(0x022d, "STEP_MOTOR_EASY_RECIPROCATING_MOTION"),// - step_motor_easy_move_to_zero_point_quick(0x022e, "STEP_MOTOR_EASY_MOVE_TO_ZERO_POINT_QUICK"),// // - mini_servo_enable(0x6601, "MINI_SERVO_ENABLE"),// - mini_servo_read_pos(0x6602, "MINI_SERVO_READ_POS"),// - mini_servo_active_cfg(0x6603, "MINI_SERVO_ACTIVE_CFG"),// - mini_servo_stop(0x6604, "MINI_SERVO_STOP"),// - mini_servo_set_mid_point(0x6607, "MINI_SERVO_SET_MID_POINT"),// - mini_servo_read_io_state(0x6608, "MINI_SERVO_READ_IO_STATE"),// - mini_servo_move_to(0x6609, "MINI_SERVO_MOVE_TO"),// - mini_servo_rotate(0x660a, "MINI_SERVO_ROTATE"),// - mini_servo_rotate_with_torque(0x660b, "MINI_SERVO_ROTATE_WITH_TORQUE"),// - mini_servo_set_cur_pos(0x660c, "MINI_SERVO_SET_CUR_POS"),// + // 步进点击控制 // - extboard_read_inio(0x6701, "EXTBOARD_READ_INIO"),// - extboard_write_outio(0x6702, "EXTBOARD_WRITE_OUTIO"),// - extboard_read_muti_inio(0x6703, "EXTBOARD_READ_MUTI_INIO"),// - extboard_read_inio_index_in_stm32(0x6704, "EXTBOARD_READ_INIO_INDEX_IN_STM32"),// - extboard_read_outio_index_in_stm32(0x6705, "EXTBOARD_READ_OUTIO_INDEX_IN_STM32"),// - extboard_read_outio(0x6706, "EXTBOARD_READ_OUTIO"),// - code_scaner_start_scan(0x6801, "CODE_SCANER_START_SCAN"),// - code_scaner_stop_scan(0x6802, "CODE_SCANER_STOP_SCAN"),// - code_scaner_result_is_ready(0x6803, "CODE_SCANER_RESULT_IS_READY"),// - code_scaner_read_scaner_result(0x6804, "CODE_SCANER_READ_SCANER_RESULT"),// - code_scaner_get_result_length(0x6805, "CODE_SCANER_GET_RESULT_LENGTH"),// + step_motor_enable(0x0201, "步进使能"),// + step_motor_read_pos(0x020b, "步进读取位置"),// + step_motor_read_enc_pos(0x020c, "步进读取编码器位置"),// + step_motor_easy_rotate(0x0211, "步进旋转"),// + step_motor_easy_move_by(0x0212, "步进相对移动"),// + step_motor_easy_move_to(0x0213, "步进绝对移动"),// + step_motor_easy_move_to_zero(0x0214, "步进归零"),// + step_motor_easy_set_current_pos(0x0215, "步进设置当前位置"),// + step_motor_easy_move_to_io(0x0216, "步进移动到IO"),// + step_motor_stop(0x0228, "步进停止"),// + step_motor_move_by(0x021d, "步进相对移动(速度可控)"), // (dpos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) + step_motor_move_to(0x021e, "步进绝对移动(速度可控)"), // (pos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) + step_motor_move_to_zero_point_quick(0x021f, "步进快速归零(速度可控)"), // (speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) + step_motor_rotate(0x0220, "步进旋转(速度可控)"), // + + step_motor_active_cfg(0x0229, "步进激活配置"),// + step_motor_read_io_state(0x022a, "步进读取IO"),// + step_motor_easy_move_to_end_point(0x022c, "步进移动到终点IO"),// + step_motor_read_tmc5130_status(0x0232, "步进读取TMC5130-STATUS"),// + step_motor_read_tmc5130_state(0x0233, "步进读取TMC5130-STATE"),// + step_motor_read_io_index_in_stm32(0x0238, "步进读取IO硬件编号"),// + step_motor_set_subdevice_reg(0x0239, "步进设置5130寄存器"),// + step_motor_get_subdevice_reg(0x023a, "步进读取5130寄存器"),// + step_motor_easy_reciprocating_motion(0x022d, "步进往复运动"),// + step_motor_easy_move_to_zero_point_quick(0x022e, "步进快速归零"),// // - fan_controler_set_speed(0x6900, "FAN_CONTROLER_SET_SPEED"),// + mini_servo_enable(0x6601, "舵机使能"),// + mini_servo_read_pos(0x6602, "舵机读取位置"),// + mini_servo_active_cfg(0x6603, "舵机激活配置"),// + mini_servo_stop(0x6604, "舵机停止"),// + mini_servo_set_mid_point(0x6607, "舵机设置中点(校准位置)"),// + mini_servo_read_io_state(0x6608, "舵机读取IO状态"),// + mini_servo_move_to(0x6609, "舵机移动到"),// + mini_servo_rotate(0x660a, "舵机旋转"),// + mini_servo_rotate_with_torque(0x660b, "舵机旋转(扭矩)"),// + mini_servo_set_cur_pos(0x660c, "舵机设置当前位置(校准使用)"),// // - temp_controler_start_hearting(0x7000, "TEMP_CONTROLER_START_HEARTING"),// - temp_controler_stop_hearting(0x7001, "TEMP_CONTROLER_STOP_HEARTING"),// - temp_controler_set_peltier_power_level(0x7002, "TEMP_CONTROLER_SET_PELTIER_POWER_LEVEL"),// - temp_controler_set_pump_level(0x7003, "TEMP_CONTROLER_SET_PUMP_LEVEL"),// - temp_controler_set_fan_level(0x7004, "TEMP_CONTROLER_SET_FAN_LEVEL"),// - temp_controler_enable_log(0x7005, "TEMP_CONTROLER_ENABLE_LOG"),// + extboard_read_inio(0x6701),// + extboard_write_outio(0x6702),// + extboard_read_muti_inio(0x6703),// + extboard_read_inio_index_in_stm32(0x6704),// + extboard_read_outio_index_in_stm32(0x6705),// + extboard_read_outio(0x6706),// + code_scaner_start_scan(0x6801),// + code_scaner_stop_scan(0x6802),// + code_scaner_result_is_ready(0x6803),// + code_scaner_read_scaner_result(0x6804),// + code_scaner_get_result_length(0x6805),// // - a8000_idcard_reader_read_raw(0x7100, "A8000_IDCARD_READER_READ_RAW"),// - a8000_idcard_write_raw(0x7101, "A8000_IDCARD_WRITE_RAW"),// - a8000_idcard_erase(0x7102, "A8000_IDCARD_ERASE"),// - a8000_idcard_earse_unlock(0x7103, "A8000_IDCARD_EARSE_UNLOCK"),// + fan_controller_set_speed(0x6900),// // - event_a8000_idcard_online(0x71c8, "EVENT_A8000_IDCARD_ONLINE"),// - event_a8000_idcard_offline(0x71c9, "EVENT_A8000_IDCARD_OFFLINE"),// + temp_controller_start_hearting(0x7000),// + temp_controller_stop_hearting(0x7001),// + temp_controller_set_peltier_power_level(0x7002),// + temp_controller_set_pump_level(0x7003),// + temp_controller_set_fan_level(0x7004),// + temp_controller_enable_log(0x7005),// // - // plate_code_scaner_push_card_and_scan(0x7301, "PLATE_CODE_SCANER_PUSH_CARD_AND_SCAN"),// - // plate_code_scaner_stop_scan(0x7302, "PLATE_CODE_SCANER_STOP_SCAN"),// - // plate_code_scaner_read_result(0x7303, "PLATE_CODE_SCANER_READ_RESULT"),// - // plate_code_scaner_read_result_point_num(0x7304, "PLATE_CODE_SCANER_READ_RESULT_POINT_NUM"),// - // plate_code_scaner_read_code(0x7305, "PLATE_CODE_SCANER_READ_CODE"),// - // plate_code_scaner_adc_readraw(0x7306, "PLATE_CODE_SCANER_ADC_READRAW"),// - // plate_code_scaner_open_laser(0x7307, "PLATE_CODE_SCANER_OPEN_LASER"),// - // plate_code_scaner_close_laser(0x7308, "PLATE_CODE_SCANER_CLOSE_LASER"),// + a8000_idcard_reader_read_raw(0x7100),// + a8000_idcard_write_raw(0x7101),// + a8000_idcard_erase(0x7102),// + a8000_idcard_erase_unlock(0x7103),// // + event_a8000_idcard_online(0x71c8),// + event_a8000_idcard_offline(0x71c9),// + // + // plate_code_scaner_push_card_and_scan(0x7301),// + // plate_code_scaner_stop_scan(0x7302),// + // plate_code_scaner_read_result(0x7303),// + // plate_code_scaner_read_result_point_num(0x7304),// + // plate_code_scaner_read_code(0x7305),// + // plate_code_scaner_adc_readraw(0x7306),// + // plate_code_scaner_open_laser(0x7307),// + // plate_code_scaner_close_laser(0x7308),// + // - pipette_set_zmbcfg(0x7401, "pipette_set_zmbcfg"), - pipette_get_zmbcfg(0x7402, "pipette_get_zmbcfg"), - pipette_set_pmbcfg(0x7403, "pipette_set_pmbcfg"), - pipette_get_pmbcfg(0x7404, "pipette_get_pmbcfg"), - pipette_set_platinfo(0x7405, "pipette_set_platinfo"), - pipette_get_platinfo(0x7406, "pipette_get_platinfo"), - pipette_set_zmvcfg(0x7407, "pipette_set_zmvcfg"), - pipette_get_zmvcfg(0x7408, "pipette_get_zmvcfg"), - pipette_set_pmvcfg(0x7409, "pipette_set_pmvcfg"), - pipette_get_pmvcfg(0x740A, "pipette_get_pmvcfg"), - pipette_set_container_info(0x740B, "pipette_set_container_info"), - pipette_get_container_info(0x740C, "pipette_get_container_info"), - pipette_set_liquid_info(0x740D, "pipette_set_liquid_info"), - pipette_get_liquid_info(0x740E, "pipette_get_liquid_info"), - pipette_get_platinfo_max_cpyid(0x7410, "pipette_get_platinfo_max_cpyid"), - pipette_get_zmvcfg_max_cpyid(0x7411, "pipette_get_zmvcfg_max_cpyid"), - pipette_get_pmvcfg_max_cpyid(0x7412, "pipette_get_pmvcfg_max_cpyid"), - pipette_get_container_info_max_cpyid(0x7413, "pipette_get_container_info_max_cpyid"), - pipette_get_liquid_info_max_cpyid(0x7414, "pipette_get_liquid_info_max_cpyid"), - pipette_set_common_cfg(0x7415, "pipette_set_common_cfg"), - pipette_get_common_cfg(0x7416, "pipette_get_common_cfg"), + pipette_set_zmbcfg(0x7401), + pipette_get_zmbcfg(0x7402), + pipette_set_pmbcfg(0x7403), + pipette_get_pmbcfg(0x7404), + pipette_set_platinfo(0x7405), + pipette_get_platinfo(0x7406), + pipette_set_zmvcfg(0x7407), + pipette_get_zmvcfg(0x7408), + pipette_set_pmvcfg(0x7409), + pipette_get_pmvcfg(0x740A), + pipette_set_container_info(0x740B), + pipette_get_container_info(0x740C), + pipette_set_liquid_info(0x740D), + pipette_get_liquid_info(0x740E), + pipette_get_platinfo_max_cpyid(0x7410), + pipette_get_zmvcfg_max_cpyid(0x7411), + pipette_get_pmvcfg_max_cpyid(0x7412), + pipette_get_container_info_max_cpyid(0x7413), + pipette_get_liquid_info_max_cpyid(0x7414), + pipette_set_common_cfg(0x7415), + pipette_get_common_cfg(0x7416), - pipette_zmotor_enable(0x7500, "pipette_zmotor_enable"), - pipette_zmotor_move_zero(0x7501, "pipette_zmotor_move_zero"), - pipette_zmotor_move_to_zero_point_quick(0x7502, "pipette_zmotor_move_to_zero_point_quick"), - pipette_zmotor_measure_distance(0x7503, "pipette_zmotor_measure_distance"), - pipette_zmotor_read_measure_distance_result(0x7504, "pipette_zmotor_read_measure_distance_result"), - pipette_zmotor_move_by(0x7505, "pipette_zmotor_move_by"), - pipette_zmotor_move_to(0x7506, "pipette_zmotor_move_to"), - pipette_zmotor_read_zero_point_state(0x7507, "pipette_zmotor_read_zero_point_state"), - pipette_zmotor_read_dev_status_cache(0x7508, "pipette_zmotor_read_dev_status_cache"), - pipette_zmotor_read_pos(0x7509, "pipette_zmotor_read_pos"), - pipette_zmotor_read_enc_pos(0x750A, "pipette_zmotor_read_enc_pos"), - pipette_zmotor_move_to_tip_deposit(0x750B, "pipette_zmotor_move_to_tip_deposit"), + pipette_zmotor_enable(0x7500), + pipette_zmotor_move_zero(0x7501), + pipette_zmotor_move_to_zero_point_quick(0x7502), + pipette_zmotor_measure_distance(0x7503), + pipette_zmotor_read_measure_distance_result(0x7504), + pipette_zmotor_move_by(0x7505), + pipette_zmotor_move_to(0x7506), + pipette_zmotor_read_zero_point_state(0x7507), + pipette_zmotor_read_dev_status_cache(0x7508), + pipette_zmotor_read_pos(0x7509), + pipette_zmotor_read_enc_pos(0x750A), + pipette_zmotor_move_to_tip_deposit(0x750B), - pipette_pump_init_device(0x7580, "pipette_pump_init_device"), - pipette_pump_take_tip(0x7581, "pipette_pump_take_tip"), - pipette_pump_deposit_tip(0x7582, "pipette_pump_put_tip"), - pipette_pump_pierce_through(0x7583, "pipette_pump_aspirate_set_param"), - pipette_pump_aspirate_set_param(0x7584, "pipette_pump_aspirate_set_param"), - pipette_pump_aspirate(0x7585, "pipette_pump_aspirate"), - pipette_get_sensor_sample_data(0x7587, "pipette_get_sensor_sample_data"), - pipette_get_sensor_sample_data_num(0x7588, "pipette_get_sensor_sample_data_num"), - pipette_read_state(0x7589, "pipette_read_state"), - pipette_pump_putbak_tip(0x758A, "pipette_pump_cutback_tip"), - pipette_read_tip_state(0x758B, "pipette_read_tip_state"), - pipette_read_pressure(0x758C, "pipette_read_pressure"), - pipette_read_capacitance(0x758D, "pipette_read_capacitance"), - pipette_pump_distribu_all_set_param(0x758E, "pipette_pump_distribu_all_set_param"), // {paramid,val}, ack:{} - pipette_pump_distribu_all(0x758F, "pipette_pump_distribu_all"), // {}, ack:{} - pipette_get_asp_pressure_data(0x7590, "pipette_get_asp_pressure_data"), // {section_off}, ack:{int16_t data[]} + pipette_pump_init_device(0x7580), + pipette_pump_take_tip(0x7581), + pipette_pump_deposit_tip(0x7582), + pipette_pump_pierce_through(0x7583), + pipette_pump_aspirate_set_param(0x7584), + pipette_pump_aspirate(0x7585), + pipette_get_sensor_sample_data(0x7587), + pipette_get_sensor_sample_data_num(0x7588), + pipette_read_state(0x7589), + pipette_pump_putbak_tip(0x758A), + pipette_read_tip_state(0x758B), + pipette_read_pressure(0x758C), + pipette_read_capacitance(0x758D), + pipette_pump_distribu_all_set_param(0x758E), // {paramid,val}, ack:{} + pipette_pump_distribu_all(0x758F), // {}, ack:{} + pipette_get_asp_pressure_data(0x7590), // {section_off}, ack:{int16_t data[]} - pipette_test_pump_move_to_x100nl(0x7600, "pipette_test_pump_move_to_x100nl"), // int32_t x100nl, int32_t vcfgindex - pipette_test_lld(0x7601, "pipette_test_lld"), // int32_t container_pos, int32_t container_cpyid, int32_t liquid_cpyid - pipette_test_move_to_container_bottom(0x7602, "pipette_test_move_to_container_bottom"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_container_bottom_section_begin(0x7603, "pipette_test_move_to_container_bottom_section_begin"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_immersion_pos(0x7604, "pipette_test_move_to_immersion_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_leaving_height_pos(0x7605, "pipette_test_move_to_leaving_height_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_jet_pos(0x7606, "pipette_test_move_to_jet_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_lld_start_search_pos(0x7607, "pipette_test_move_to_lld_start_search_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_fix_water_level_pos(0x7608, "pipette_test_move_to_fix_water_level_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_pierce_pos(0x7609, "pipette_test_move_to_pierce_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_move_to_lld_end_pos(0x760A, "pipette_test_move_to_lld_end_pos"), // int32_t container_pos, int32_t container_cpyid, - pipette_test_connectivity(0x760B, "pipette_test_connectivity"), // 测试电缆连接性 {}, ack:{} + pipette_test_pump_move_to_x100nl(0x7600), // int32_t x100nl, int32_t vcfgindex + pipette_test_lld(0x7601), // int32_t container_pos, int32_t container_cpyid, int32_t liquid_cpyid + pipette_test_move_to_container_bottom(0x7602), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_container_bottom_section_begin(0x7603), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_immersion_pos(0x7604), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_leaving_height_pos(0x7605), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_jet_pos(0x7606), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_lld_start_search_pos(0x7607), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_fix_water_level_pos(0x7608), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_pierce_pos(0x7609), // int32_t container_pos, int32_t container_cpyid, + pipette_test_move_to_lld_end_pos(0x760A), // int32_t container_pos, int32_t container_cpyid, + pipette_test_connectivity(0x760B), // 测试电缆连接性 {}, ack:{} ; - public final static int ATTACH_IS_BYTES = 1; - public final static int ATTACH_IS_INT32 = 2; - public final int index; - public final String chName; - - - // public final int cmdAttachType = ATTACH_IS_INT32; - // public final int receiptAttachType = ATTACH_IS_INT32; - // public final boolean trace = true; - // public final boolean actionCmd = true; + public final int index; + public final String chName; CmdId(int index, String chname) { this.index = index; this.chName = chname; } + CmdId(int index) { + this.index = index; + this.chName = this.name().toUpperCase(); + } + public int toInt() { return index; } @@ -228,50 +238,29 @@ public enum CmdId { return e.toString(); } } - return "unkown(" + val + ")"; - } - - public String getChname() { - return chName; - } - - public Boolean eq(Integer index) { - return this.index == index; - } - - - public int getCmdAttachType() { - return switch (this) { - case a8000_idcard_write_raw -> ATTACH_IS_BYTES; - default -> ATTACH_IS_INT32; - }; + return "unknown(" + val + ")"; } - public int getReceiptAttachType() { - return switch (this) { - case a8k_opt_v2_read_raw, a8000_idcard_reader_read_raw -> ATTACH_IS_BYTES; - default -> ATTACH_IS_INT32; - }; - } - public boolean isTrace() { - return true; - } + // + // public boolean isActionCmd() { + // return switch (this) { + // case module_get_status, + // module_get_error, + // xymotor_read_pos, + // xymotor_read_inio, + // step_motor_read_io_state, + // extboard_read_inio, + // extboard_read_muti_inio, + // module_get_reg, + // module_set_reg, + // code_scaner_result_is_ready -> false; + // default -> true; + // }; + // } + // public boolean isTrace() { + // return true; + // } - public boolean isActionCmd() { - return switch (this) { - case module_get_status, - module_get_error, - xymotor_read_pos, - xymotor_read_inio, - step_motor_read_io_state, - extboard_read_inio, - extboard_read_muti_inio, - module_get_reg, - module_set_reg, - code_scaner_result_is_ready -> false; - default -> true; - }; - } } diff --git a/src/main/java/a8k/app/iflytophald/utils/PacketFormater.java b/src/main/java/a8k/app/iflytophald/utils/PacketFormater.java new file mode 100644 index 0000000..4d2558b --- /dev/null +++ b/src/main/java/a8k/app/iflytophald/utils/PacketFormater.java @@ -0,0 +1,73 @@ +package a8k.app.iflytophald.utils; + +import a8k.app.iflytophald.info.CmdIdInfoMgr; +import a8k.app.iflytophald.type.protocol.*; +import a8k.app.utils.ByteArrayUtils; +import org.springframework.util.Assert; + +public class PacketFormater { + + static public String packetToString(A8kPacket packet) { + int packetType = packet.getPacketType(); + String ret = ""; + + CmdId cmdId = CmdId.valueOf(packet.getCmdId()); + Assert.isTrue(cmdId != null, "cmdId is null"); + if (packetType == A8kPacket.PACKET_TYPE_CMD) { + + if (cmdId.equals(CmdId.module_get_reg) || cmdId.equals(CmdId.module_set_reg)) { + RegIndex regIndex = RegIndex.valueOf(packet.getContentI32(0)); + if (regIndex != null) { + ret = String.format("[CMD ] index:[%d] %s %s %s(%d) %d", packet.getPacketIndex(), cmdId, + MId.valueOf(packet.getModuleId()), regIndex, regIndex.index, packet.getContentI32(1)); + } else { + ret = String.format("[CMD ] index:[%d] %s unkown_index(%d) %d", packet.getPacketIndex(), cmdId, + packet.getContentI32(0), packet.getContentI32(1)); + } + } else { + if (CmdIdInfoMgr.getCmdAttachType(cmdId).equals(A8kCmdAttachmentType.INT32S)) { + ret = String.format("[CMD ] index:[%d] (%s %s(%d) :param:[%s])", packet.getPacketIndex(), cmdId, + MId.valueOf(packet.getModuleId()), packet.getModuleId(), formatInt32ATTACH(packet.getCmdContent())); + } else { + ret = String.format("[CMD ] index:[%d] (%s %s(%d) :param:[%s])", packet.getPacketIndex(), cmdId, + MId.valueOf(packet.getModuleId()), packet.getModuleId(), ByteArrayUtils.toByteString(packet.getCmdContent())); + } + } + + } else if (packetType == A8kPacket.PACKET_TYPE_ACK) { + if (CmdIdInfoMgr.getReceiptAttachType(cmdId).equals(A8kCmdAttachmentType.INT32S)) { + ret = String.format("[ACK ] index:[%d] (%s :[%s])", packet.getPacketIndex(), cmdId, + formatInt32ATTACH(packet.getCmdContent())); + } else { + ret = String.format("[ACK ] index:[%d] (%s :[%s])", packet.getPacketIndex(), cmdId, + ByteArrayUtils.toByteString(packet.getCmdContent())); + } + } else if (packetType == A8kPacket.PACKET_TYPE_ERROR_ACK) { + ret = String.format("[EACK ] index:[%d] (%s :[%s])", packet.getPacketIndex(), cmdId, (packet.getContentI32(0))); + } else if (packetType == A8kPacket.PACKET_TYPE_EVENT) { + if (CmdIdInfoMgr.getCmdAttachType(cmdId).equals(A8kCmdAttachmentType.INT32S)) { + ret = String.format("[EVENT] index:[%d] (%s %s(%d) :[%s])", packet.getPacketIndex(), cmdId, + MId.valueOf(packet.getModuleId()), packet.getModuleId(), formatInt32ATTACH(packet.getCmdContent())); + } else { + ret = String.format("[EVENT] index:[%d] (%s %s(%d) :[%s])", packet.getPacketIndex(), cmdId, + MId.valueOf(packet.getModuleId()), packet.getModuleId(), ByteArrayUtils.toByteString(packet.getCmdContent())); + } + } else { + ret = String.format("Unknown packet type: %d", packetType); + } + return ret; + } + + + private static String formatInt32ATTACH(byte[] attach) { + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < attach.length; i += 4) { + if (i + 3 >= attach.length) + break; + if (i != 0) + ret.append(","); + ret.append(String.format("%d", ByteArrayUtils.read32bit(attach, i))); + } + return ret.toString(); + } +} diff --git a/src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java b/src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java index 349a1bb..3fbe578 100644 --- a/src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java +++ b/src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java @@ -17,6 +17,7 @@ import a8k.app.type.a8k.proj.A8kReactionFlowType; import a8k.app.utils.*; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @@ -26,6 +27,7 @@ import java.util.List; @Component @Slf4j +@RequiredArgsConstructor public class AppConsumablesScanService { @Schema(description = "耗材扫描报告") @@ -59,17 +61,17 @@ public class AppConsumablesScanService { } } - @Resource - ConsumablesScanCtrlService scanCtrlService; - @Resource - PreReactionStateMgr preReactionStateMgr; - @Resource - ConsumablesMgrService consumablesMgrService; - @Resource - GStateMgrService gstate; - - @Resource - ProjInfoMgrService projInfoMgrService; + + private final ConsumablesScanCtrlService scanCtrlService; + + private final PreReactionStateMgr preReactionStateMgr; + + private final ConsumablesMgrService consumablesMgrService; + + private final GStateMgrService gstate; + + + private final ProjInfoMgrService projInfoMgrService; /** diff --git a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java index 9c0f204..682dfae 100644 --- a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java @@ -230,7 +230,7 @@ public class MainFlowCtrlScheduler { deviceWorkStateMgrService.setFatalErrorFlag(appErrors.getFirst()); for (AppError appError : appErrors) { - appEventBusService.pushEvent(ZAppPromptFactory.buildAppPromptEvent(appError)); + pushAppErrorEvent(appError); } } //清空正在处理的试管架 @@ -238,7 +238,7 @@ public class MainFlowCtrlScheduler { tubeStateMgr.resetAll(); tubeFeedingCtrlService.ejectTubeHolder(); } catch (AppException e) { - appEventBusService.pushEvent(ZAppPromptFactory.buildAppPromptEvent(e)); + pushAppErrorEvent(e.getError()); } log.info("MainFlowCtrlScheduler work thread stopped"); @@ -248,4 +248,19 @@ public class MainFlowCtrlScheduler { } } + void pushAppErrorEvent(AppError error) { + if (error == null) { + return; + } + + /* + * 急停触发错误不在前端显示 + */ + if (error.eq(A8kEcode.EMERGENCY_KEY_TRIGGER)) { + return; + } + + appEventBusService.pushEvent(ZAppPromptFactory.buildAppPromptEvent(error)); + } + }