BakeoutController-Basic  0.1
A Controller for the Omicron vacuum chamber
ModBusConnectionManager.java
1 package kernel.modbus;
2 
3 import com.ghgande.j2mod.modbus.io.ModbusSerialTransaction;
4 import com.ghgande.j2mod.modbus.io.ModbusTransaction;
5 import com.ghgande.j2mod.modbus.msg.ModbusMessage;
6 import com.ghgande.j2mod.modbus.msg.ModbusRequest;
7 import com.ghgande.j2mod.modbus.msg.ModbusResponse;
8 import com.ghgande.j2mod.modbus.net.SerialConnection;
10 import org.jetbrains.annotations.Contract;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import java.io.DataInput;
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataInputStream;
17 import java.io.DataOutputStream;
18 import java.io.IOException;
19 import java.io.DataOutput;
20 
24 public class ModBusConnectionManager implements ModbusConnector {
25 
29  private static final Logger log = LoggerFactory.getLogger(
31 
36  private ModbusPortConfiguration desiredPortConfiguration;
37 
41  private PortShutdownThread portShutdownThread;
42 
46  private SerialConnection connection;
47 
48  private static final Integer recieveTimeOut = 4000;
49 
50  private static final Integer numberOfRetries = 1;
51 
55  @Override
57  return this.desiredPortConfiguration;
58  }
59 
63  @Override
64  public void setPortConfiguration(
65  ModbusPortConfiguration portConfiguration
66  ){
67  desiredPortConfiguration = portConfiguration;
68  }
69 
75  @Override
76  public Boolean isPortOpen(){
77  if (connection == null){
78  return Boolean.FALSE;
79  } else {
80  return connection.isOpen();
81  }
82  }
83 
87  @Override
88  public void close(){
89  connection.close();
90  removeShutdownThread();
91  }
92 
102  @Override
103  public ModbusTransaction getTransactionForRequest(ModbusRequest request)
104  throws WrappedModbusException, IllegalStateException {
105 
106  log.debug(
107  "Creating transaction for request {}", request.getHexMessage()
108  );
109 
110  if (!isPortOpen()){
111  log.debug("Port {} is not open. Opening now", this);
112  openConnection();
113  log.debug("Port {} successfully opened", this);
114  } else {
115  log.debug("Port {} is open, using for connection", this);
116  }
117  connection.setTimeout(recieveTimeOut);
118 
119  ModbusSerialTransaction transaction = new ModbusSerialTransaction();
120  transaction.setSerialConnection(connection);
121  transaction.setRequest(request);
122  transaction.setRetries(numberOfRetries);
123 
124  return transaction;
125  }
126 
135  @Override
136  public Float parseFloatFromResponse(ModbusMessage response) throws
137  ClassCastException, IOException {
138  ModbusResponse inputRegistersResponse = (ModbusResponse) response;
139  ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
140  DataOutput writer = new DataOutputStream(byteBuffer);
141  log.debug(
142  "Received response {}. Parsing to float",
143  inputRegistersResponse.toString()
144  );
145 
146  inputRegistersResponse.writeData(writer);
147 
148  byte[] dataToRead = processByteArray(byteBuffer.toByteArray());
149 
150  DataInput reader = new DataInputStream(
151  new ByteArrayInputStream(dataToRead)
152  );
153 
154  return reader.readFloat();
155 
156  }
157 
168  @Override
169  public String parseStringFromResponse(ModbusMessage response) throws
170  ClassCastException, IOException {
171  ModbusResponse inputRegistersResponse = (ModbusResponse) response;
172 
173  ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
174  DataOutput writer = new DataOutputStream(byteBuffer);
175  log.debug(
176  "Received response {}. Parsing to string",
177  inputRegistersResponse.toString()
178  );
179 
180  inputRegistersResponse.writeData(writer);
181 
182  DataInput reader = new DataInputStream(
183  new ByteArrayInputStream(byteBuffer.toByteArray())
184  );
185 
186  return reader.readLine();
187  }
188 
198  private void openConnection() throws IllegalStateException,
199  WrappedModbusException {
200  assertPortClosed();
201  assertHasPortConfiguration();
202 
203  connection = new SerialConnection(
204  desiredPortConfiguration.getSerialParameters()
205  );
206 
207  createShutdownThread();
208 
209  try {
210  connection.open();
211  } catch (Exception error){
212  throw new WrappedModbusException(error);
213  }
214  }
215 
219  private void assertPortClosed() throws IllegalStateException {
220  if (this.isPortOpen()){
221  throw new IllegalStateException("MODBUS port is not open.");
222  }
223  }
224 
229  private void assertHasPortConfiguration() throws IllegalStateException {
230  if (desiredPortConfiguration == null){
231  throw new IllegalStateException(
232  "Attempted to open a port without configuration being set"
233  );
234  }
235  }
236 
242  private void createShutdownThread(){
243  portShutdownThread = new PortShutdownThread(connection);
244  Runtime.getRuntime().addShutdownHook(portShutdownThread);
245  }
246 
251  private void removeShutdownThread(){
252  Runtime.getRuntime().removeShutdownHook(portShutdownThread);
253  }
254 
277  @Contract(pure = true)
278  private static byte[] processByteArray(byte[] inputBytes){
279  byte[] outputBytes = new byte[inputBytes.length - 1];
280 
281  for (int index = 0; index < outputBytes.length; index++){
282  outputBytes[index] = inputBytes[
283  inputBytes.length - 1 - index
284  ];
285  }
286 
287  return outputBytes;
288  }
289 
294  private class PortShutdownThread extends Thread {
298  private final Logger log = LoggerFactory.getLogger
299  (PortShutdownThread.class);
300 
304  private final SerialConnection connection;
305 
309  public PortShutdownThread(SerialConnection connection){
310  this.connection = connection;
311  }
312 
316  @Override
317  public void run(){
318  log.info("Connection {} caught shutdown signal. Closing",
319  connection.toString());
320  connection.close();
321  log.info("MODBUS Connection {} successfully closed",
322  connection.toString());
323  }
324  }
325 }
ModbusTransaction getTransactionForRequest(ModbusRequest request)
void setPortConfiguration(ModbusPortConfiguration portConfiguration)
String parseStringFromResponse(ModbusMessage response)
SerialParameters getSerialParameters()
Float parseFloatFromResponse(ModbusMessage response)
Git Repo