diff --git a/src/main/java/a8k/a8k_can_protocol/Packet.java b/src/main/java/a8k/a8k_can_protocol/A8kPacket.java similarity index 90% rename from src/main/java/a8k/a8k_can_protocol/Packet.java rename to src/main/java/a8k/a8k_can_protocol/A8kPacket.java index f71443e..0334b4d 100644 --- a/src/main/java/a8k/a8k_can_protocol/Packet.java +++ b/src/main/java/a8k/a8k_can_protocol/A8kPacket.java @@ -2,7 +2,7 @@ package a8k.a8k_can_protocol; import a8k.utils.ByteArray; -public class Packet { +public class A8kPacket { /** * typedef struct { * uint16_t packetindex; // 0: @@ -35,24 +35,28 @@ public class Packet { public static final int PACKET_TYPE_ERROR_ACK = 2; public static final int PACKET_TYPE_EVENT = 3; - public Packet(byte[] cmd) { + public static final int CMD_OVERTIME = 100; + + public A8kPacket(byte[] cmd) { raw = new byte[cmd.length]; System.arraycopy(cmd, 0, raw, 0, cmd.length); } - - public Integer getPacketIndex() { + public void setPacketIndex(int packetIndex) { + ByteArray.setU16bit(raw,0,packetIndex); + } + public int getPacketIndex() { return ByteArray.readU16bit(raw, 0); } - public Integer getCmdId() { + public int getCmdId() { return ByteArray.readU16bit((raw), 2) * 256 + ByteArray.readU8bit(raw, 4); } - public Integer getPacketType() { + public int getPacketType() { return ByteArray.readU8bit(raw, 5); } - public Integer getModuleId() { + public int getModuleId() { return ByteArray.readU16bit(raw, 6); } @@ -62,7 +66,7 @@ public class Packet { return cmdcontent; } - public Integer getContentI32(int index) { + public int getContentI32(int index) { return ByteArray.readU16bit(raw, 8 + index * 4); } @@ -70,7 +74,6 @@ public class Packet { return ByteArray.toByteString(raw); } - public String toString() { int packetType = getPacketType(); String ret = ""; diff --git a/src/main/java/a8k/a8k_can_protocol/Errorcode.java b/src/main/java/a8k/a8k_can_protocol/Errorcode.java index 7a648e6..f889888 100644 --- a/src/main/java/a8k/a8k_can_protocol/Errorcode.java +++ b/src/main/java/a8k/a8k_can_protocol/Errorcode.java @@ -20,7 +20,7 @@ public class Errorcode { public static final int kcmd_param_num_error = (100 + 14); public static final int kcheckcode_is_error = (100 + 15); public static final int killegal_operation = (100 + 16); - + public static final int kaction_overtime = (100 + 17); /*********************************************************************************************************************** * 模块错误码 * ***********************************************************************************************************************/ @@ -98,138 +98,74 @@ public class Errorcode { public static final int kwater_cooling_pelter_is_error = (900 + 4); // static public String toString(Integer ecode) { - switch (ecode) { - case ksucc: - return "ksucc"; - case kfail: - return "kfail"; - case kparam_out_of_range: - return "kparam_out_of_range"; - case kcmd_not_support: - return "kcmd_not_support"; - case kdevice_is_busy: - return "kdevice_is_busy"; - case kdevice_is_offline: - return "kdevice_is_offline"; - case kovertime: - return "kovertime"; - case knoack: - return "knoack"; - case kerrorack: - return "kerrorack"; - case kdevice_offline: - return "kdevice_offline"; - case ksubdevice_overtime: - return "ksubdevice_overtime"; - case kbuffer_not_enough: - return "kbuffer_not_enough"; - case kcmd_param_num_error: - return "kcmd_param_num_error"; - case kcheckcode_is_error: - return "kcheckcode_is_error"; - case killegal_operation: - return "killegal_operation"; - case kmodule_opeation_break_by_user: - return "kmodule_opeation_break_by_user"; - case kmodule_not_find_reg: - return "kmodule_not_find_reg"; - case kxymotor_x_find_zero_edge_fail: - return "kxymotor_x_find_zero_edge_fail"; - case kxymotor_y_find_zero_edge_fail: - return "kxymotor_y_find_zero_edge_fail"; - case kxymotor_not_enable: - return "kxymotor_not_enable"; - case kxymotor_target_pos_outof_range: - return "kxymotor_target_pos_outof_range"; - case kpipette_error_NoError: - return "kpipette_error_NoError"; - case kpipette_error_InitFail: - return "kpipette_error_InitFail"; - case kpipette_error_InvalidCmd: - return "kpipette_error_InvalidCmd"; - case kpipette_error_InvalidArg: - return "kpipette_error_InvalidArg"; - case kpipette_error_PressureSensorError: - return "kpipette_error_PressureSensorError"; - case kpipette_error_OverPressure: - return "kpipette_error_OverPressure"; - case kpipette_error_LLDError: - return "kpipette_error_LLDError"; - case kpipette_error_DeviceNotInit: - return "kpipette_error_DeviceNotInit"; - case kpipette_error_TipPopError: - return "kpipette_error_TipPopError"; - case kpipette_error_PumpOverload: - return "kpipette_error_PumpOverload"; - case kpipette_error_TipDrop: - return "kpipette_error_TipDrop"; - case kpipette_error_CanBusError: - return "kpipette_error_CanBusError"; - case kpipette_error_InvalidChecksum: - return "kpipette_error_InvalidChecksum"; - case kpipette_error_EEPROMError: - return "kpipette_error_EEPROMError"; - case kpipette_error_CmdBufferEmpty: - return "kpipette_error_CmdBufferEmpty"; - case kpipette_error_CmdBufferOverflow: - return "kpipette_error_CmdBufferOverflow"; - case kpipette_error_TipBlock: - return "kpipette_error_TipBlock"; - case kpipette_error_AirSuction: - return "kpipette_error_AirSuction"; - case kpipette_error_Bubble: - return "kpipette_error_Bubble"; - case kpipette_error_VolumeError: - return "kpipette_error_VolumeError"; - case kpipette_error_TipAlreadyLoad: - return "kpipette_error_TipAlreadyLoad"; - case kpipette_error_TipLoadFail: - return "kpipette_error_TipLoadFail"; - case kpipette_error_tipisload_when_lld_prepare: - return "kpipette_error_tipisload_when_lld_prepare"; - case kpipette_error_uninited: - return "kpipette_error_uninited"; - case kpipette_error_not_lld_prepare: - return "kpipette_error_not_lld_prepare"; - case kpipette_error_pump_load_val_is_not_empty: - return "kpipette_error_pump_load_val_is_not_empty"; - case kstep_motor_not_found_zero_point: - return "kstep_motor_not_found_zero_point"; - case kstep_motor_not_go_zero: - return "kstep_motor_not_go_zero"; - case kstep_motor_over_temperature: - return "kstep_motor_over_temperature"; - case kstep_motor_over_voltage: - return "kstep_motor_over_voltage"; - case kstep_motor_run_overtime: - return "kstep_motor_run_overtime"; - case kstep_motor_not_enable: - return "kstep_motor_not_enable"; - case kstep_motor_ioindex_out_of_range: - return "kstep_motor_ioindex_out_of_range"; - case kstep_motor_subic_reset: - return "kstep_motor_subic_reset"; - case kstep_motor_drv_err: - return "kstep_motor_drv_err"; - case kstep_motor_uv_cp: - return "kstep_motor_uv_cp"; - case kstep_motor_not_found_point_edge: - return "kstep_motor_not_found_point_edge"; - case kmini_servo_not_enable: - return "kmini_servo_not_enable"; - case kmini_servo_mode_not_support: - return "kmini_servo_mode_not_support"; - case kfan_hardware_fault: - return "kfan_hardware_fault"; - case kwater_cooling_fan_error: - return "kwater_cooling_fan_error"; - case kwater_cooling_temperature_sensor_error: - return "kwater_cooling_temperature_sensor_error"; - case kwater_cooling_pump_is_error: - return "kwater_cooling_pump_is_error"; - case kwater_cooling_pelter_is_error: - return "kwater_cooling_pelter_is_error"; - } - return "unkown" + "(" + ecode + ")"; - } + return switch (ecode) { + case ksucc -> "ksucc"; + case kfail -> "kfail"; + case kparam_out_of_range -> "kparam_out_of_range"; + case kcmd_not_support -> "kcmd_not_support"; + case kdevice_is_busy -> "kdevice_is_busy"; + case kdevice_is_offline -> "kdevice_is_offline"; + case kovertime -> "kovertime"; + case knoack -> "knoack"; + case kerrorack -> "kerrorack"; + case kdevice_offline -> "kdevice_offline"; + case ksubdevice_overtime -> "ksubdevice_overtime"; + case kbuffer_not_enough -> "kbuffer_not_enough"; + case kcmd_param_num_error -> "kcmd_param_num_error"; + case kcheckcode_is_error -> "kcheckcode_is_error"; + case killegal_operation -> "killegal_operation"; + case kaction_overtime -> "kaction_overtime"; + case kmodule_opeation_break_by_user -> "kmodule_opeation_break_by_user"; + case kmodule_not_find_reg -> "kmodule_not_find_reg"; + case kxymotor_x_find_zero_edge_fail -> "kxymotor_x_find_zero_edge_fail"; + case kxymotor_y_find_zero_edge_fail -> "kxymotor_y_find_zero_edge_fail"; + case kxymotor_not_enable -> "kxymotor_not_enable"; + case kxymotor_target_pos_outof_range -> "kxymotor_target_pos_outof_range"; + case kpipette_error_NoError -> "kpipette_error_NoError"; + case kpipette_error_InitFail -> "kpipette_error_InitFail"; + case kpipette_error_InvalidCmd -> "kpipette_error_InvalidCmd"; + case kpipette_error_InvalidArg -> "kpipette_error_InvalidArg"; + case kpipette_error_PressureSensorError -> "kpipette_error_PressureSensorError"; + case kpipette_error_OverPressure -> "kpipette_error_OverPressure"; + case kpipette_error_LLDError -> "kpipette_error_LLDError"; + case kpipette_error_DeviceNotInit -> "kpipette_error_DeviceNotInit"; + case kpipette_error_TipPopError -> "kpipette_error_TipPopError"; + case kpipette_error_PumpOverload -> "kpipette_error_PumpOverload"; + case kpipette_error_TipDrop -> "kpipette_error_TipDrop"; + case kpipette_error_CanBusError -> "kpipette_error_CanBusError"; + case kpipette_error_InvalidChecksum -> "kpipette_error_InvalidChecksum"; + case kpipette_error_EEPROMError -> "kpipette_error_EEPROMError"; + case kpipette_error_CmdBufferEmpty -> "kpipette_error_CmdBufferEmpty"; + case kpipette_error_CmdBufferOverflow -> "kpipette_error_CmdBufferOverflow"; + case kpipette_error_TipBlock -> "kpipette_error_TipBlock"; + case kpipette_error_AirSuction -> "kpipette_error_AirSuction"; + case kpipette_error_Bubble -> "kpipette_error_Bubble"; + case kpipette_error_VolumeError -> "kpipette_error_VolumeError"; + case kpipette_error_TipAlreadyLoad -> "kpipette_error_TipAlreadyLoad"; + case kpipette_error_TipLoadFail -> "kpipette_error_TipLoadFail"; + case kpipette_error_tipisload_when_lld_prepare -> "kpipette_error_tipisload_when_lld_prepare"; + case kpipette_error_uninited -> "kpipette_error_uninited"; + case kpipette_error_not_lld_prepare -> "kpipette_error_not_lld_prepare"; + case kpipette_error_pump_load_val_is_not_empty -> "kpipette_error_pump_load_val_is_not_empty"; + case kstep_motor_not_found_zero_point -> "kstep_motor_not_found_zero_point"; + case kstep_motor_not_go_zero -> "kstep_motor_not_go_zero"; + case kstep_motor_over_temperature -> "kstep_motor_over_temperature"; + case kstep_motor_over_voltage -> "kstep_motor_over_voltage"; + case kstep_motor_run_overtime -> "kstep_motor_run_overtime"; + case kstep_motor_not_enable -> "kstep_motor_not_enable"; + case kstep_motor_ioindex_out_of_range -> "kstep_motor_ioindex_out_of_range"; + case kstep_motor_subic_reset -> "kstep_motor_subic_reset"; + case kstep_motor_drv_err -> "kstep_motor_drv_err"; + case kstep_motor_uv_cp -> "kstep_motor_uv_cp"; + case kstep_motor_not_found_point_edge -> "kstep_motor_not_found_point_edge"; + case kmini_servo_not_enable -> "kmini_servo_not_enable"; + case kmini_servo_mode_not_support -> "kmini_servo_mode_not_support"; + case kfan_hardware_fault -> "kfan_hardware_fault"; + case kwater_cooling_fan_error -> "kwater_cooling_fan_error"; + case kwater_cooling_temperature_sensor_error -> "kwater_cooling_temperature_sensor_error"; + case kwater_cooling_pump_is_error -> "kwater_cooling_pump_is_error"; + case kwater_cooling_pelter_is_error -> "kwater_cooling_pelter_is_error"; + default -> "unkown" + "(" + ecode + ")"; + }; + } } diff --git a/src/main/java/a8k/a8k_can_protocol/ModuleId.java b/src/main/java/a8k/a8k_can_protocol/ModuleId.java index 2cab19e..b40dd4b 100644 --- a/src/main/java/a8k/a8k_can_protocol/ModuleId.java +++ b/src/main/java/a8k/a8k_can_protocol/ModuleId.java @@ -1,5 +1,64 @@ package a8k.a8k_can_protocol; public class ModuleId { + public static final int ArmXYId = 11;//机械臂XY + public static final int ArmZId = 81;//机械臂Z + public static final int FeederId = 60;//出入料模块 + public static final int IdCardReaderId = 101; //A8K读卡器 + public static final int IncubatorTempCtrlId = 51;//温度控制 + public static final int MaterialScannerId = 83;//物料扫码器 + public static final int MotorCardWarehouseMoveId = 21;//板夹仓移动电机 + public static final int MotorCardWarehousePushId = 22;//板夹仓推杆电机 + public static final int MotorIncubatorRotateId = 71;//孵育盘旋转 + public static final int MotorTestCardPullId = 92;//板卡推杆电机 + public static final int MotorTestCardScanId = 91;//板卡扫描电机 + public static final int MotorTubeBodyClipId = 31;//试管固定夹爪电机 + public static final int MotorTubeMoveUpDownId = 32;//摇匀升降电机 + public static final int MotorTubeRackExitId = 63;//出料电机 + public static final int MotorTubeRackFeedId = 61;//入料电机 + public static final int MotorTubeRackMoveId = 62;//试管架平移电机 + public static final int MotorTubeShakeId = 33;//试管摇匀电机 + public static final int PipetteId = 82;//移液枪 + public static final int ScannerId = 93;//扫描仪 + public static final int ServoTubeCapClipId = 35;//摇匀试管帽夹爪 + public static final int ServoTubeMoveFrontBackId = 34;//摇匀前后电机 + public static final int ServoTubeRackTubePushId = 36;//试管架旋转固定舵机 + public static final int ServoTubeRackTubeRotateId = 37;//试管架旋转舵机 + public static final int TestCardWarehouseId = 41;//测试板仓 + public static final int TrashBoxId = 40;//废料盒 + public static final int TubeRackScannerId = 64;//试管架扫码器 + public static final int WbTubeFanId = 42;//气溶胶风扇 + public static String ModuleId2Name(int moduleId) { + return switch (moduleId) { + case ArmXYId -> "ArmXYId"; + case ArmZId -> "ArmZId"; + case FeederId -> "FeederId"; + case IdCardReaderId -> "IdCardReaderId"; + case IncubatorTempCtrlId -> "IncubatorTempCtrlId"; + case MaterialScannerId -> "MaterialScannerId"; + case MotorCardWarehouseMoveId -> "MotorCardWarehouseMoveId"; + case MotorCardWarehousePushId -> "MotorCardWarehousePushId"; + case MotorIncubatorRotateId -> "MotorIncubatorRotateId"; + case MotorTestCardPullId -> "MotorTestCardPullId"; + case MotorTestCardScanId -> "MotorTestCardScanId"; + case MotorTubeBodyClipId -> "MotorTubeBodyClipId"; + case MotorTubeMoveUpDownId -> "MotorTubeMoveUpDownId"; + case MotorTubeRackExitId -> "MotorTubeRackExitId"; + case MotorTubeRackFeedId -> "MotorTubeRackFeedId"; + case MotorTubeRackMoveId -> "MotorTubeRackMoveId"; + case MotorTubeShakeId -> "MotorTubeShakeId"; + case PipetteId -> "PipetteId"; + case ScannerId -> "ScannerId"; + case ServoTubeCapClipId -> "ServoTubeCapClipId"; + case ServoTubeMoveFrontBackId -> "ServoTubeMoveFrontBackId"; + case ServoTubeRackTubePushId -> "ServoTubeRackTubePushId"; + case ServoTubeRackTubeRotateId -> "ServoTubeRackTubeRotateId"; + case TestCardWarehouseId -> "TestCardWarehouseId"; + case TrashBoxId -> "TrashBoxId"; + case TubeRackScannerId -> "TubeRackScannerId"; + case WbTubeFanId -> "WbTubeFanId"; + default -> "UnknownModuleId(" + moduleId + ")"; + }; + } } diff --git a/src/main/java/a8k/appbean/AppEvent.java b/src/main/java/a8k/appbean/AppEvent.java new file mode 100644 index 0000000..a624f89 --- /dev/null +++ b/src/main/java/a8k/appbean/AppEvent.java @@ -0,0 +1,4 @@ +package a8k.appbean; + +public class AppEvent { +} diff --git a/src/main/java/a8k/appbean/AppEventBus.java b/src/main/java/a8k/appbean/AppEventBus.java new file mode 100644 index 0000000..344ef90 --- /dev/null +++ b/src/main/java/a8k/appbean/AppEventBus.java @@ -0,0 +1,4 @@ +package a8k.appbean; + +public class AppEventBus { +} diff --git a/src/main/java/a8k/appbean/AppException.java b/src/main/java/a8k/appbean/AppException.java new file mode 100644 index 0000000..18bf9ec --- /dev/null +++ b/src/main/java/a8k/appbean/AppException.java @@ -0,0 +1,4 @@ +package a8k.appbean; + +public class AppException { +} diff --git a/src/main/java/a8k/appbean/HardwareException.java b/src/main/java/a8k/appbean/HardwareException.java new file mode 100644 index 0000000..b990021 --- /dev/null +++ b/src/main/java/a8k/appbean/HardwareException.java @@ -0,0 +1,27 @@ +package a8k.appbean; + +import a8k.a8k_can_protocol.Errorcode; +import a8k.a8k_can_protocol.ModuleId; + +public class HardwareException extends Exception { + // 构造函数 + + int errorCode; + int moduleId; + + public HardwareException() { + super(); + } + + public HardwareException(int moduleId, int HardwareErrorCode) { + super(String.format("Module ID %s has error code %s", ModuleId.ModuleId2Name(moduleId), Errorcode.toString(HardwareErrorCode))); + } + + int getModuleId() { + return moduleId; + } + + int getErrorCode() { + return errorCode; + } +} diff --git a/src/main/java/a8k/base_hardware/A8kCanBusService.java b/src/main/java/a8k/base_hardware/A8kCanBusService.java index c722461..dddf881 100644 --- a/src/main/java/a8k/base_hardware/A8kCanBusService.java +++ b/src/main/java/a8k/base_hardware/A8kCanBusService.java @@ -1,6 +1,9 @@ package a8k.base_hardware; -import a8k.a8k_can_protocol.Packet; +import a8k.a8k_can_protocol.A8kPacket; +import a8k.a8k_can_protocol.CmdId; +import a8k.a8k_can_protocol.Errorcode; +import a8k.appbean.HardwareException; import a8k.utils.ByteArray; import jakarta.annotation.PostConstruct; import org.java_websocket.client.WebSocketClient; @@ -14,6 +17,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; @Component public class A8kCanBusService { @@ -39,19 +45,31 @@ public class A8kCanBusService { * } * */ - public String uri; //assign by application.yml - private WebSocketClient client; - Timer timer = new Timer(); - boolean need_reconnect = false; + public String uri; //assign by application.yml + private WebSocketClient client; + public BlockingQueue receiptQueue; + public BlockingQueue eventQueue; + boolean isWaitingReceipt = false; + int waitingReceiptIndex = 0; + int packetIndex; + + boolean debugFlag = false; + + Timer autoConnectTimer = new Timer(); @PostConstruct public void init() throws URISyntaxException { + + logger.info("BaseHardwareService initilized"); + packetIndex = 0; if (this.uri == null) { //this.uri = "ws://127.0.0.1:19005"; this.uri = "ws://192.168.8.10:19005"; } + receiptQueue = new LinkedBlockingQueue(); + eventQueue = new LinkedBlockingQueue<>(); URI uri = new URI(this.uri); @@ -79,7 +97,7 @@ public class A8kCanBusService { client.connect(); - timer.schedule(new TimerTask() { + autoConnectTimer.schedule(new TimerTask() { @Override public void run() { if (!client.isOpen()) { @@ -97,23 +115,63 @@ public class A8kCanBusService { } - - - // cmdId, - public void callcmd(Integer moduleId, Integer cmdId, Integer param0) { - + //TODO + public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer[] params) { + return null; } - public void callcmd(Integer moduleId, Integer cmdId, Integer param0, Integer param1) { + //TODO + public void callblockcmd(Integer moduleId, Integer cmdId, Integer[] params,int acitionOvertime) { + //调用sendCmdAutoResend + // 通过kmodule_get_status判断指令是否完成,超时未完成则报错,则调用module_stop,同时抛出异常 + // + return; + } + //TODO + public A8kPacket sendCmdAutoResend(A8kPacket pack, int overtime) throws HardwareException { + //调用sendCmd, + // 如果捕获到超时异常,则重发,最多重发三次 + // 如果是其他异常,则直接抛出异常。 + return null; } - public void callcmd(Integer moduleId, Integer cmdId, Integer param0, Integer param1, Integer param2) { - } + private A8kPacket sendCmd(A8kPacket pack, int overtime) throws HardwareException { + pack.setPacketIndex(packetIndex); + waitingReceiptIndex = packetIndex; + packetIndex = packetIndex + 1; + if (packetIndex > 10000) { + packetIndex = 1; + } + receiptQueue.clear(); + isWaitingReceipt = true; + String txpacket = pack.toByteString(); - public void callcmd(Integer moduleId, Integer cmdId, Integer param0, Integer param1, Integer param2, Integer param3) { + if (debugFlag && pack.getCmdId() != CmdId.kmodule_get_status) { + logger.info("tx:{}:({})", pack, txpacket); + } + client.send(txpacket); + A8kPacket receipt; + try { + receipt = receiptQueue.poll(overtime, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + isWaitingReceipt = false; + throw new HardwareException(pack.getModuleId(), Errorcode.kovertime); + } + isWaitingReceipt = false; + if (receipt == null) { + throw new HardwareException(pack.getModuleId(), Errorcode.kovertime); + } + if (receipt.getPacketType() == A8kPacket.PACKET_TYPE_ERROR_ACK) { + throw new HardwareException(pack.getModuleId(), receipt.getContentI32(0)); + } + try { + Thread.sleep(10); + } catch (InterruptedException ignored) { + } + return receipt; } /** @@ -126,17 +184,31 @@ public class A8kCanBusService { return; } - if (rx.length < Packet.PACKET_MIN_LEN) { + if (rx.length < A8kPacket.PACKET_MIN_LEN) { logger.warn("rx is too short"); return; } - Packet packet = new Packet(rx); - logger.info("RX {}", packet); + A8kPacket packet = new A8kPacket(rx); + if (debugFlag && packet.getCmdId() != CmdId.kmodule_get_status) { + logger.info("RX {}:({})", packet, rx); + } + if (packet.getPacketType() == A8kPacket.PACKET_TYPE_ACK || packet.getPacketType() == A8kPacket.PACKET_TYPE_ERROR_ACK) { + if (isWaitingReceipt) { + if (waitingReceiptIndex == packet.getPacketIndex()) { + receiptQueue.add(packet); + } + } + } + + if (packet.getPacketType() == A8kPacket.PACKET_TYPE_EVENT) { + eventQueue.add(packet); + } } + public static void main(String[] args) { A8kCanBusService service = new A8kCanBusService(); try { @@ -144,6 +216,19 @@ public class A8kCanBusService { } catch (URISyntaxException e) { logger.error(e.getMessage()); } + + Thread thread = new Thread(() -> { + while (true) { + A8kPacket packet = null; + try { + packet = service.receiptQueue.take(); + logger.info("poll receipt {}", packet); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + thread.run(); } } diff --git a/src/main/java/a8k/base_hardware/ReconnectingWebSocketClient.java b/src/main/java/a8k/base_hardware/ReconnectingWebSocketClient.java deleted file mode 100644 index 6f5543f..0000000 --- a/src/main/java/a8k/base_hardware/ReconnectingWebSocketClient.java +++ /dev/null @@ -1,82 +0,0 @@ -package a8k.base_hardware; - -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Timer; -import java.util.TimerTask; - - -public class ReconnectingWebSocketClient extends WebSocketClient { - public static final Logger logger = LoggerFactory.getLogger(A8kCanBusService.class); - - private URI serverUri; - private Timer reconnectTimer; - private boolean reconnecting; - - public ReconnectingWebSocketClient(URI serverUri) { - super(serverUri); - this.serverUri = serverUri; - this.reconnectTimer = new Timer("ReconnectTimer"); - this.reconnecting = false; - } - - @Override - public void onOpen(ServerHandshake handshakedata) { - System.out.println("WebSocket opened to: " + serverUri); - cancelReconnect(); - } - - @Override - public void onMessage(String message) { - System.out.println("Received message: " + message); - } - - @Override - public void onClose(int code, String reason, boolean remote) { - System.out.println("WebSocket closed. Code: " + code + ", Reason: " + reason); - scheduleReconnect(); - } - - @Override - public void onError(Exception ex) { - System.err.println("WebSocket error: " + ex.getMessage()); - scheduleReconnect(); - } - - private void scheduleReconnect() { - if (!reconnecting) { - reconnecting = true; - reconnectTimer.schedule(new TimerTask() { - @Override - public void run() { - if (!isOpen()) { - System.out.println("Attempting to reconnect to: " + serverUri); - reconnect(); - } - } - }, 5000); // 5 seconds delay before attempting to reconnect - } - } - - private void cancelReconnect() { - if (reconnecting) { - reconnecting = false; - reconnectTimer.cancel(); - reconnectTimer.purge(); - } - } - - - public static void main(String[] args) throws URISyntaxException, InterruptedException { - URI serverUri = new URI("ws://localhost:8080"); // Replace with your WebSocket server URI - ReconnectingWebSocketClient client = new ReconnectingWebSocketClient(serverUri); - client.connect(); - Thread.sleep(60000); // Example: Keep the program running for 1 minute - client.close(); - } -} diff --git a/src/main/java/a8k/controler/ZhaoheTestControler.java b/src/main/java/a8k/controler/ZhaoheTestControler.java deleted file mode 100644 index fcc1693..0000000 --- a/src/main/java/a8k/controler/ZhaoheTestControler.java +++ /dev/null @@ -1,16 +0,0 @@ -package a8k.controler; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -@Controller -public class ZhaoheTestControler { - - @PostMapping("/test") - @ResponseBody - public String hello() { - return "Hello, welcome to the ultimate Spring Boot service!"; - } -} diff --git a/src/main/java/a8k/service/hardware/MotorTubeRackExitService.java b/src/main/java/a8k/service/hardware/MotorTubeRackExitService.java new file mode 100644 index 0000000..75e15fa --- /dev/null +++ b/src/main/java/a8k/service/hardware/MotorTubeRackExitService.java @@ -0,0 +1,9 @@ +package a8k.service.hardware; + +import org.springframework.stereotype.Component; + +@Component +public class MotorTubeRackExitService { + + +} diff --git a/src/main/java/a8k/service/hardware/MotorTubeRackMoveContrlService.java b/src/main/java/a8k/service/hardware/MotorTubeRackMoveContrlService.java new file mode 100644 index 0000000..cbfbb2c --- /dev/null +++ b/src/main/java/a8k/service/hardware/MotorTubeRackMoveContrlService.java @@ -0,0 +1,4 @@ +package a8k.service.hardware; + +public class MotorTubeRackMoveContrlService { +} diff --git a/src/main/java/a8k/service/hardware/MotorTubeRackMoveService.java b/src/main/java/a8k/service/hardware/MotorTubeRackMoveService.java new file mode 100644 index 0000000..f8d3ddb --- /dev/null +++ b/src/main/java/a8k/service/hardware/MotorTubeRackMoveService.java @@ -0,0 +1,4 @@ +package a8k.service.hardware; + +public class MotorTubeRackMoveService { +} diff --git a/src/main/java/a8k/utils/ByteArray.java b/src/main/java/a8k/utils/ByteArray.java index 8500c5f..355dafb 100644 --- a/src/main/java/a8k/utils/ByteArray.java +++ b/src/main/java/a8k/utils/ByteArray.java @@ -26,6 +26,11 @@ public class ByteArray { return (code[index + 1] & 255) << 8 | code[index] & 255; } + public static void setU16bit(byte[] code, int index, int value) { + code[index+1] = (byte) (value >> 8); + code[index] = (byte) value; + } + public static int readS16bit(byte[] code, int index) { if (index + 2 >= code.length) return 0;