You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
8.3 KiB

  1. package com.dreamworks.boditech.driver;
  2. import com.dreamworks.boditech.driver.actuator.*;
  3. import com.dreamworks.boditech.driver.connection.ComSerialPort;
  4. import com.dreamworks.boditech.driver.consumable.CsmBufferTubeA;
  5. import com.dreamworks.boditech.driver.consumable.CsmBufferTubeB;
  6. import com.dreamworks.boditech.driver.consumable.CsmLargeBufferTube;
  7. import com.dreamworks.boditech.driver.consumable.CsmPipetteTip;
  8. import com.dreamworks.boditech.service.RuntimeOptionService;
  9. import com.dreamworks.boditech.utils.MyByteBuffer;
  10. import jakarta.annotation.PostConstruct;
  11. import jakarta.annotation.Resource;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.beans.factory.annotation.Value;
  15. import org.springframework.stereotype.Component;
  16. import java.nio.ByteBuffer;
  17. import java.nio.ByteOrder;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. @Component
  23. public class Device {
  24. private static final Logger LOG = LoggerFactory.getLogger(Device.class);
  25. @Value("${app.device.debug}")
  26. private Boolean debug;
  27. @Resource
  28. private ComSerialPort serialPort;
  29. @Resource
  30. private RuntimeOptionService runtimeOptionService;
  31. // actuators
  32. private final Map<Integer, Actuator> actuators = new HashMap<Integer, Actuator>();
  33. // pipette tips
  34. private final List<CsmPipetteTip> pipetteTips = new ArrayList<CsmPipetteTip>();
  35. // buffer tube larges
  36. private final List<CsmLargeBufferTube> largeBufferTubes = new ArrayList<CsmLargeBufferTube>();
  37. // buffer tube A
  38. private final List<CsmBufferTubeA> bufferTubeAList = new ArrayList<CsmBufferTubeA>();
  39. // buffer tube B
  40. private final List<CsmBufferTubeB> bufferTubeBList = new ArrayList<CsmBufferTubeB>();
  41. // message index
  42. private short messageIndex = 0;
  43. @PostConstruct
  44. public void init() {
  45. this.appendActuator(new ActModuleTestTubeRackMovement(ActuatorModule.TEST_TUBE_RACK_MOVEMENT, this));
  46. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_RACK_FEED_MOTOR, this));
  47. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_RACK_MOVE_MOTOR, this));
  48. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_RACK_EXIT_MOTOR, this));
  49. this.appendActuator(new ActCodeScanner(ActuatorModule.TEST_TUBE_RACK_SCANNER, this));
  50. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR, this));
  51. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR, this));
  52. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_SHAKING_SHAKE_MOTOR, this));
  53. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_SHAKING_ROTATE_MOTOR, this));
  54. this.appendActuator(new ActMotor(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR, this));
  55. this.appendActuator(new ActArmXY(ActuatorModule.ARM_XY, this));
  56. this.appendActuator(new ActMotor(ActuatorModule.ARM_Z_MOTOR, this));
  57. this.appendActuator(new ActPipette(ActuatorModule.ARM_Z_PIPETTE, this));
  58. }
  59. // append actuator
  60. private void appendActuator(Actuator actuator) {
  61. this.actuators.put(actuator.getMid(), actuator);
  62. }
  63. // get actuator by module id
  64. public Actuator getActuator(Integer mid) {
  65. return this.actuators.get(mid);
  66. }
  67. // append buffer tube A
  68. public void appendBufferTubeA( Integer areaIndex, Integer amount ) {
  69. for (int i = 0; i<amount; i++ ) {
  70. CsmBufferTubeA tube = new CsmBufferTubeA();
  71. tube.areaIndex = areaIndex;
  72. tube.position = i;
  73. this.bufferTubeAList.add(tube);
  74. }
  75. }
  76. // get buffer tube A
  77. public CsmBufferTubeA getBufferTubeA( String projectName ) {
  78. for (CsmBufferTubeA tube : this.bufferTubeAList) {
  79. if (!tube.projectName.equals(projectName)) {
  80. continue;
  81. }
  82. this.bufferTubeAList.remove(tube);
  83. return tube;
  84. }
  85. throw new RuntimeException("no buffer tube A for project " + projectName);
  86. }
  87. // append buffer tube B
  88. public void appendBufferTubeB( Integer areaIndex, Integer amount ) {
  89. for (int i = 0; i<amount; i++ ) {
  90. CsmBufferTubeB tube = new CsmBufferTubeB();
  91. tube.areaIndex = areaIndex;
  92. tube.position = i;
  93. this.bufferTubeBList.add(tube);
  94. }
  95. }
  96. // get buffer tube B
  97. public CsmBufferTubeB getBufferTubeB( String projectName ) {
  98. for (CsmBufferTubeB tube : this.bufferTubeBList) {
  99. if (!tube.projectName.equals(projectName)) {
  100. continue;
  101. }
  102. this.bufferTubeBList.remove(tube);
  103. return tube;
  104. }
  105. throw new RuntimeException("no buffer tube B for project " + projectName);
  106. }
  107. // append pipette tip
  108. public void appendPipetteTip( Integer areaIndex, Integer amount ) {
  109. for (int i = 0; i<amount; i++ ) {
  110. CsmPipetteTip tip = new CsmPipetteTip();
  111. tip.areaIndex = areaIndex;
  112. tip.position = i;
  113. this.pipetteTips.add(tip);
  114. }
  115. }
  116. // get pipette tip
  117. public CsmPipetteTip getPipetteTip() {
  118. if ( this.pipetteTips.isEmpty() ) {
  119. throw new RuntimeException("no pipette tip");
  120. }
  121. CsmPipetteTip tip = this.pipetteTips.remove(0);
  122. return tip;
  123. }
  124. // append large buffer tube
  125. public void appendLargeBufferTube( Integer position ) {
  126. CsmLargeBufferTube tube = new CsmLargeBufferTube();
  127. tube.position = position;
  128. this.largeBufferTubes.removeIf(tmp -> tmp.position.equals(position));
  129. this.largeBufferTubes.add(tube);
  130. }
  131. // get large buffer tube
  132. public CsmLargeBufferTube getLargeBufferTube( String projectName ) {
  133. CsmLargeBufferTube tube = null;
  134. for ( CsmLargeBufferTube tmp : this.largeBufferTubes ) {
  135. if ( !tmp.projectName.equals(projectName) ) {
  136. continue ;
  137. }
  138. if ( tmp.isEmpty() ) {
  139. continue;
  140. }
  141. tube = tmp;
  142. break;
  143. }
  144. if ( null == tube ) {
  145. throw new RuntimeException("no large buffer tube");
  146. }
  147. return tube;
  148. }
  149. // get location by name
  150. public Integer getLocationByName( String name ) {
  151. String key = "device.location." + name;
  152. Integer value = this.runtimeOptionService.getInteger(key);
  153. return value;
  154. }
  155. // call device command and wait for response
  156. public ByteBuffer call( Integer cmd, Integer mid, Object ... params ) {
  157. int length = 2 + 2 + 1 + 1 + 2;
  158. for ( Object param : params ) {
  159. if ( param instanceof Integer ) {
  160. length += 4;
  161. } else {
  162. throw new RuntimeException("param type error");
  163. }
  164. }
  165. int subCmdId = cmd & 0xFF;
  166. int mainCmdId = (cmd >> 8) & 0xFFFF;
  167. int moduleId = mid;
  168. ByteBuffer request = ByteBuffer.allocate(length);
  169. request.order(ByteOrder.LITTLE_ENDIAN);
  170. request.putShort(this.messageIndex);
  171. request.putShort((short)mainCmdId); // main cmd id
  172. request.put((byte)subCmdId); // sub cmd id
  173. request.put((byte)0); // directive type
  174. request.putShort((short)moduleId); // mid
  175. for ( Object param : params ) {
  176. if ( param instanceof Integer ) {
  177. request.putInt((Integer)param);
  178. }
  179. }
  180. this.messageIndex ++;
  181. if ( this.debug ) {
  182. return this.serialPortCall(request);
  183. }
  184. return this.prodCall(cmd, mid, params);
  185. }
  186. // call device command in debug mode
  187. private ByteBuffer serialPortCall(ByteBuffer request) {
  188. LOG.info("Device serial port => {}", MyByteBuffer.toHex(request));
  189. this.serialPort.write(request);
  190. ByteBuffer response = ByteBuffer.allocate(0);
  191. while ( 0 == response.capacity() ) {
  192. try {
  193. Thread.sleep(300);
  194. } catch (InterruptedException e) {
  195. e.printStackTrace();
  196. }
  197. response = this.serialPort.read();
  198. }
  199. LOG.info("Device serial port <= {}", MyByteBuffer.toHex(response));
  200. return response;
  201. }
  202. private ByteBuffer prodCall(Integer cmd, Integer mid, Object[] params) {
  203. System.out.println("Device prodCall");
  204. return null;
  205. }
  206. }