13 changed files with 268 additions and 100 deletions
-
BINdoc/通讯协议.pdf
-
14src/main/java/com/dreamworks/boditech/BoditechApplication.java
-
37src/main/java/com/dreamworks/boditech/driver/Device.java
-
12src/main/java/com/dreamworks/boditech/driver/connection/ClientRequest.java
-
47src/main/java/com/dreamworks/boditech/driver/connection/ComWebsocket.java
-
124src/main/java/com/dreamworks/boditech/driver/connection/ComWebsocketClient.java
-
22src/main/java/com/dreamworks/boditech/driver/consumable/CsmSampleTube.java
-
28src/main/java/com/dreamworks/boditech/driver/task/step/StepCapTube.java
-
1src/main/java/com/dreamworks/boditech/driver/task/step/StepManager.java
-
2src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java
-
63src/main/java/com/dreamworks/boditech/utils/BoditechDeviceClient.java
-
14src/main/java/com/dreamworks/boditech/utils/MyByteBuffer.java
-
4src/main/resources/application.yml
@ -0,0 +1,12 @@ |
|||
package com.dreamworks.boditech.driver.connection; |
|||
import java.nio.ByteBuffer; |
|||
public class ClientRequest { |
|||
// message id |
|||
public short id; |
|||
// parameter |
|||
public ByteBuffer parameter; |
|||
// response |
|||
public ByteBuffer response; |
|||
// error code |
|||
public Integer errorCode = 0; |
|||
} |
@ -0,0 +1,47 @@ |
|||
package com.dreamworks.boditech.driver.connection; |
|||
import jakarta.annotation.PostConstruct; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Component; |
|||
import java.net.URI; |
|||
import java.net.URISyntaxException; |
|||
import java.nio.ByteBuffer; |
|||
|
|||
@Component |
|||
public class ComWebsocket { |
|||
@Value("${app.device.connectionType}") |
|||
private String connectionType; |
|||
@Value("${app.device.wsuri}") |
|||
private String deviceWsUrl; |
|||
// websocket client |
|||
private ComWebsocketClient client; |
|||
|
|||
@PostConstruct |
|||
public void init() { |
|||
if ( !this.connectionType.equals("WebSocket") ) { |
|||
return ; |
|||
} |
|||
this.open(); |
|||
} |
|||
|
|||
// open websocket connection |
|||
public void open() { |
|||
URI uri = null; |
|||
try { |
|||
uri = new URI(this.deviceWsUrl); |
|||
} catch (URISyntaxException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
|
|||
this.client = new ComWebsocketClient(uri); |
|||
this.client.connect(); |
|||
} |
|||
|
|||
// call device method and wait for response |
|||
public ByteBuffer call(ClientRequest request ) { |
|||
this.client.call(request); |
|||
if ( 0 != request.errorCode ) { |
|||
throw new RuntimeException("device error : " + request.errorCode); |
|||
} |
|||
return request.response; |
|||
} |
|||
} |
@ -0,0 +1,124 @@ |
|||
package com.dreamworks.boditech.driver.connection; |
|||
import com.dreamworks.boditech.utils.MyByteBuffer; |
|||
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.nio.ByteBuffer; |
|||
import java.nio.ByteOrder; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Objects; |
|||
public class ComWebsocketClient extends WebSocketClient { |
|||
// message type : ack |
|||
private static final byte MESSAGE_TYPE_ACK = 0x01; |
|||
// message type : error ack |
|||
private static final byte MESSAGE_TYPE_ERROR_ACK = 0x02; |
|||
// message type : event |
|||
private static final byte MESSAGE_TYPE_EVENT = 0x03; |
|||
// logger |
|||
private static final Logger LOG = LoggerFactory.getLogger(ComWebsocketClient.class); |
|||
// request list |
|||
private final List<ClientRequest> requestList = new ArrayList<>(); |
|||
|
|||
// constructor |
|||
public ComWebsocketClient(URI uri ) { |
|||
super(uri); |
|||
} |
|||
|
|||
/** |
|||
* call device method and wait for response |
|||
* @param request request |
|||
*/ |
|||
public void call( ClientRequest request ) { |
|||
this.requestList.add(request); |
|||
int index = this.requestList.indexOf(request); |
|||
ClientRequest requestItem = this.requestList.get(index); |
|||
synchronized (requestItem) { |
|||
String cmd = MyByteBuffer.toHex(request.parameter); |
|||
cmd = cmd.replace(" ",""); |
|||
LOG.info("device => {}", cmd); |
|||
this.send(cmd); |
|||
try { |
|||
requestItem.wait(); |
|||
} catch (InterruptedException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* event handler for receiving text message from device |
|||
* @param text message from device |
|||
*/ |
|||
@Override |
|||
public void onMessage(String text) { |
|||
LOG.info("device <= {}", text); |
|||
ByteBuffer message = MyByteBuffer.fromHex(text); |
|||
message.order(ByteOrder.LITTLE_ENDIAN); |
|||
byte messageType = message.get(5); |
|||
if ( ComWebsocketClient.MESSAGE_TYPE_ACK == messageType ) { |
|||
this.onMessageHandleAck(message); |
|||
} else if ( ComWebsocketClient.MESSAGE_TYPE_ERROR_ACK == messageType ) { |
|||
this.onMessageHandleErrorAck(message); |
|||
} else if ( ComWebsocketClient.MESSAGE_TYPE_EVENT == messageType ) { |
|||
this.onMessageHandleEvent(message); |
|||
} else { |
|||
throw new RuntimeException("unknown message type"); |
|||
} |
|||
} |
|||
|
|||
// handle ack message |
|||
private void onMessageHandleAck(ByteBuffer message) { |
|||
ClientRequest request = this.getRequestMessage(message); |
|||
synchronized (Objects.requireNonNull(request)) { |
|||
request.response = message; |
|||
request.notify(); |
|||
} |
|||
} |
|||
|
|||
// handle error ack message |
|||
private void onMessageHandleErrorAck(ByteBuffer message) { |
|||
ClientRequest request = this.getRequestMessage(message); |
|||
synchronized (Objects.requireNonNull(request)) { |
|||
request.response = null; |
|||
request.errorCode = message.getInt(8); |
|||
request.notify(); |
|||
} |
|||
} |
|||
|
|||
// get request message |
|||
private ClientRequest getRequestMessage( ByteBuffer message ) { |
|||
short messageId = message.getShort(0); |
|||
for ( ClientRequest requestItem : this.requestList ) { |
|||
if ( requestItem.id == messageId ) { |
|||
return requestItem; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
// handle event message |
|||
private void onMessageHandleEvent( ByteBuffer message ) { |
|||
// @TODO : handle event |
|||
throw new RuntimeException("not implemented"); |
|||
} |
|||
|
|||
@Override |
|||
public void onOpen(ServerHandshake serverHandshake) { |
|||
LOG.info("device connected"); |
|||
} |
|||
|
|||
@Override |
|||
public void onClose(int i, String s, boolean b) { |
|||
LOG.info("close"); |
|||
throw new RuntimeException("device connection closed"); |
|||
} |
|||
|
|||
@Override |
|||
public void onError(Exception e) { |
|||
LOG.error("error", e); |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.dreamworks.boditech.driver.task.step; |
|||
import com.dreamworks.boditech.driver.Device; |
|||
import com.dreamworks.boditech.driver.actuator.ActMotor; |
|||
import com.dreamworks.boditech.driver.actuator.ActuatorModule; |
|||
import com.dreamworks.boditech.driver.task.Executor; |
|||
import com.dreamworks.boditech.driver.task.Task; |
|||
import com.dreamworks.boditech.driver.task.TaskTest; |
|||
public class StepCapTube extends StepBase { |
|||
@Override |
|||
public void execute(Executor executor, Task task) { |
|||
TaskTest taskTest = (TaskTest)task; |
|||
if ( !taskTest.getSampleTube().hasCap() ) { |
|||
return ; |
|||
} |
|||
|
|||
Device device = executor.getDevice(); |
|||
ActMotor testTubeMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR); |
|||
ActMotor testTubeCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR); |
|||
ActMotor testTubeClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR); |
|||
|
|||
testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); |
|||
testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); |
|||
testTubeMoveMotor.moveTo("shakeTestTubeMoveStandby"); |
|||
testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); |
|||
testTubeClipMotor.rotate(ActMotor.ROTATE_DIRECTION_COUNTER_CLOCKWISE); |
|||
testTubeClipMotor.stop(); |
|||
} |
|||
} |
@ -1,63 +0,0 @@ |
|||
package com.dreamworks.boditech.utils; |
|||
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.nio.ByteBuffer; |
|||
public class BoditechDeviceClient extends WebSocketClient { |
|||
public interface OnMessageCallback { |
|||
void onCallback(ByteBuffer buffer); |
|||
} |
|||
|
|||
private static final Logger LOG = LoggerFactory.getLogger(BoditechDeviceClient.class); |
|||
|
|||
private OnMessageCallback onMessageCallback; |
|||
|
|||
public BoditechDeviceClient(URI uri ) { |
|||
super(uri); |
|||
} |
|||
|
|||
public void setOnMessageCallback( OnMessageCallback callback ) { |
|||
this.onMessageCallback = callback; |
|||
} |
|||
|
|||
@Override |
|||
public void onOpen(ServerHandshake serverHandshake) { |
|||
LOG.info("device connected"); |
|||
} |
|||
|
|||
/** |
|||
* event handler for receiving binary message from device |
|||
* @param buffer message from device |
|||
*/ |
|||
@Override |
|||
public void onMessage(ByteBuffer buffer) { |
|||
LOG.info("on message (binary) :{}", buffer); |
|||
if ( this.onMessageCallback != null ) { |
|||
this.onMessageCallback.onCallback(buffer); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* event handler for receiving text message from device |
|||
* @param text message from device |
|||
*/ |
|||
@Override |
|||
public void onMessage(String text) { |
|||
LOG.info("on message (text) : {}", text); |
|||
if ( this.onMessageCallback != null ) { |
|||
this.onMessageCallback.onCallback(ByteBuffer.wrap(text.getBytes())); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void onClose(int i, String s, boolean b) { |
|||
LOG.info("close"); |
|||
} |
|||
|
|||
@Override |
|||
public void onError(Exception e) { |
|||
LOG.error("error", e); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue