package com.cuhka.neo.monitor;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
public class ArduinoReader implements AutoCloseable {
private final SerialPort port;
private InputStream inputStream;
private final Logger logger = Logger.getLogger(ArduinoReader.class.getName());
public ArduinoReader(CommPortIdentifier identifier, int block) throws PortInUseException, IOException {
this(openPort(identifier, block));
}
public ArduinoReader(SerialPort port) {
this.port = port;
}
private static SerialPort openPort(CommPortIdentifier identifier, int block) throws PortInUseException {
if (identifier.getPortType() == CommPortIdentifier.PORT_SERIAL) {
SerialPort port = (SerialPort)identifier.open(ArduinoReader.class.getName(), block);
try {
port.setSerialPortParams(115_200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
} catch (UnsupportedCommOperationException e) {
throw new AssertionError(String.format("Cannot configure serial port %s", identifier.getName()));
}
return port;
}
throw new IllegalArgumentException(String.format("Port %s is not a serial port", identifier.getName()));
}
public Optional<DoorState> readNextState() throws IOException {
if (inputStream == null) {
logger.fine("Opening serial port stream");
inputStream = port.getInputStream();
}
if (inputStream.available() > 0) {
int read = inputStream.read();
logger.finest(() -> String.format("Read from %s '%c'", port.getName(), read));
switch (read) {
case 'C':
return Optional.of(DoorState.CLOSED);
case 'O':
return Optional.of(DoorState.OPEN);
}
}
return Optional.empty();
}
@Override
public void close() {
logger.fine(() -> "Closing " + this.getClass().getSimpleName());
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.log(Level.WARNING, "Error while closing serial port stream" ,e);
}
}
port.close();
}
}