Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit ebb3f4f

Browse files
committed
Implement serial service: Add SerialConnector
1 parent 6d96407 commit ebb3f4f

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package org.codeoverflow.chatoverflow.requirement.service.serial
2+
3+
import java.io.PrintStream
4+
5+
import com.fazecast.jSerialComm.{SerialPort, SerialPortInvalidPortException}
6+
import org.codeoverflow.chatoverflow.WithLogger
7+
import org.codeoverflow.chatoverflow.connector.Connector
8+
9+
/**
10+
* The serial connector allows to communicate with a device connected to the pcs serial port (like an Arduino)
11+
*
12+
* @param sourceIdentifier the port descriptor of the serial port to which the device is connected
13+
*/
14+
class SerialConnector(override val sourceIdentifier: String) extends Connector(sourceIdentifier) with WithLogger {
15+
16+
override protected var requiredCredentialKeys: List[String] = List()
17+
18+
private var serialPort: Option[SerialPort] = None
19+
private var out: Option[PrintStream] = None
20+
private val serialPortInputListener = new SerialPortInputListener
21+
22+
/**
23+
* Sets the baud rate of the com port to a new value
24+
*
25+
* @param baudRate the new baud rate
26+
* @throws java.lang.IllegalStateException if the serial port is not available yet
27+
*/
28+
@throws(classOf[IllegalStateException])
29+
def setBaudRate(baudRate: Int): Unit = {
30+
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
31+
serialPort.get.setBaudRate(baudRate)
32+
}
33+
34+
/**
35+
*
36+
* @throws java.lang.IllegalStateException if the serial port is not available yet
37+
* @return the baud rate of the com port
38+
*/
39+
@throws(classOf[IllegalStateException])
40+
def getBaudRate: Int = {
41+
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
42+
serialPort.get.getBaudRate
43+
}
44+
45+
/**
46+
*
47+
* @throws java.lang.IllegalStateException if the serial port is not available yet
48+
* @return print stream that outputs to the port
49+
*/
50+
@throws(classOf[IllegalStateException])
51+
def getPrintStream: PrintStream = {
52+
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
53+
out.get
54+
}
55+
56+
/**
57+
* Adds a new input listener that receives all data
58+
* @param listener a listener that handles incoming data in a byte array
59+
*/
60+
def addInputListener(listener: Array[Byte] => Unit): Unit = {
61+
serialPortInputListener.addDataAvailableListener(_ => {
62+
val buffer = new Array[Byte](serialPort.get.bytesAvailable())
63+
serialPort.get.readBytes(buffer, buffer.length) //FIXME DOES IT CRASH?
64+
listener(buffer)
65+
})
66+
}
67+
68+
/**
69+
* Opens a connection with the serial port
70+
*/
71+
override def start(): Boolean = {
72+
try {
73+
serialPort = Some(SerialPort.getCommPort(sourceIdentifier))
74+
if (serialPort.get.openPort(1000)) {
75+
serialPort.get.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0)
76+
out = Some(new PrintStream(serialPort.get.getOutputStream))
77+
serialPort.get.addDataListener(serialPortInputListener)
78+
true
79+
} else {
80+
logger error s"Could not open serial port $sourceIdentifier"
81+
false
82+
}
83+
} catch {
84+
case e: SerialPortInvalidPortException =>
85+
logger error s"Source identifier $sourceIdentifier is invalid: ${e.getMessage}"
86+
false
87+
}
88+
}
89+
90+
/**
91+
* Closes the connection with the port
92+
*/
93+
override def stop(): Boolean = {
94+
serialPort.foreach(_.closePort())
95+
true
96+
}
97+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.codeoverflow.chatoverflow.requirement.service.serial
2+
3+
import com.fazecast.jSerialComm.{SerialPort, SerialPortDataListener, SerialPortEvent}
4+
5+
import scala.collection.mutable.ListBuffer
6+
7+
class SerialPortInputListener extends SerialPortDataListener {
8+
9+
private val listeners = ListBuffer[SerialPortEvent => Unit]()
10+
11+
override def getListeningEvents: Int = SerialPort.LISTENING_EVENT_DATA_AVAILABLE
12+
13+
override def serialEvent(event: SerialPortEvent): Unit = {
14+
if (event.getEventType == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
15+
listeners.foreach(listener => listener(event))
16+
}
17+
}
18+
19+
def addDataAvailableListener(listener: SerialPortEvent => Unit): Unit = listeners += listener
20+
}

0 commit comments

Comments
 (0)