Browse Source

完善急停逻辑

master
zhaohe 3 days ago
parent
commit
77410e1412
  1. 2
      src/main/java/a8k/app/controler/api/v1/app/assistant/ApiRetTestControler.java
  2. 114
      src/main/java/a8k/app/iflytophald/channel/A8kCanBusCommunicationChannel.java
  3. 4
      src/main/java/a8k/app/iflytophald/config/ActionCommands.java
  4. 161
      src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java
  5. 14
      src/main/java/a8k/app/iflytophald/driver/WaterTemperatureControllerDriver.java
  6. 119
      src/main/java/a8k/app/iflytophald/info/CmdIdInfoMgr.java
  7. 7
      src/main/java/a8k/app/iflytophald/type/protocol/A8kCmdAttachmentType.java
  8. 93
      src/main/java/a8k/app/iflytophald/type/protocol/A8kPacket.java
  9. 411
      src/main/java/a8k/app/iflytophald/type/protocol/CmdId.java
  10. 73
      src/main/java/a8k/app/iflytophald/utils/PacketFormater.java
  11. 24
      src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java
  12. 19
      src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java

2
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")

114
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<A8kPacket> 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<Integer> 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<String> callLocalCmd(String path) {
private HttpResponse<String> 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<String> 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<String> ret = null;
try {
ret = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
log.info("ret: \t{}", ret.body());
} catch (Exception e) {
log.error("callcmd error", e);
}
}
}

4
src/main/java/a8k/app/iflytophald/config/ActionCommands.java

@ -0,0 +1,4 @@
package a8k.app.iflytophald.config;
public class ActionCommands {
}

161
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<Long, ThreadVar> threadVars = new LinkedHashMap<>();
private final Map<Long, ThreadVar> 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 {

14
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 {

119
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;
}
/**
* 判断是否是动作命令
* <p>
* 动作命令是指移动的命令, 例如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);
}
}

7
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数组
}

93
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());

411
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;
};
}
}

73
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();
}
}

24
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;
/**

19
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));
}
}
Loading…
Cancel
Save