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

Commit 74174e9

Browse files
committed
Add Serial in- and output
1 parent ebb3f4f commit 74174e9

File tree

4 files changed

+85
-26
lines changed

4 files changed

+85
-26
lines changed

build.sbt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ libraryDependencies ++= Seq(
5757
resolvers += "jcenter-bintray" at "http://jcenter.bintray.com"
5858
libraryDependencies += "net.dv8tion" % "JDA" % "4.ALPHA.0_82"
5959

60+
//Serial Communication
61+
libraryDependencies += "com.fazecast" % "jSerialComm" % "[2.0.0,3.0.0)"
62+
6063
// ---------------------------------------------------------------------------------------------------------------------
6164
// PLUGIN FRAMEWORK DEFINITIONS
6265
// ---------------------------------------------------------------------------------------------------------------------

src/main/scala/org/codeoverflow/chatoverflow/requirement/service/serial/SerialConnector.scala

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.codeoverflow.chatoverflow.requirement.service.serial
22

3-
import java.io.PrintStream
3+
import java.io.{InputStream, PrintStream}
44

55
import com.fazecast.jSerialComm.{SerialPort, SerialPortInvalidPortException}
66
import org.codeoverflow.chatoverflow.WithLogger
@@ -9,55 +9,46 @@ import org.codeoverflow.chatoverflow.connector.Connector
99
/**
1010
* The serial connector allows to communicate with a device connected to the pcs serial port (like an Arduino)
1111
*
12-
* @param sourceIdentifier the port descriptor of the serial port to which the device is connected
12+
* @param sourceIdentifier r the unique source identifier to identify this connector
1313
*/
1414
class SerialConnector(override val sourceIdentifier: String) extends Connector(sourceIdentifier) with WithLogger {
1515

16-
override protected var requiredCredentialKeys: List[String] = List()
16+
override protected var optionalCredentialKeys: List[String] = List("baudRate")
17+
override protected var requiredCredentialKeys: List[String] = List("port")
1718

1819
private var serialPort: Option[SerialPort] = None
1920
private var out: Option[PrintStream] = None
21+
private var in: Option[InputStream] = None
2022
private val serialPortInputListener = new SerialPortInputListener
2123

2224
/**
23-
* Sets the baud rate of the com port to a new value
24-
*
25-
* @param baudRate the new baud rate
2625
* @throws java.lang.IllegalStateException if the serial port is not available yet
26+
* @return print stream that outputs to the port
2727
*/
2828
@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
29+
def getPrintStream: PrintStream = {
30+
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
31+
out.get
4332
}
4433

4534
/**
46-
*
4735
* @throws java.lang.IllegalStateException if the serial port is not available yet
48-
* @return print stream that outputs to the port
36+
* @return a inputstream that receives all data from the port
4937
*/
5038
@throws(classOf[IllegalStateException])
51-
def getPrintStream: PrintStream = {
39+
def getInputStream: InputStream = {
5240
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
53-
out.get
41+
in.get
5442
}
5543

5644
/**
5745
* Adds a new input listener that receives all data
5846
* @param listener a listener that handles incoming data in a byte array
47+
* @throws java.lang.IllegalStateException if the serial port is not available yet
5948
*/
49+
@throws(classOf[IllegalStateException])
6050
def addInputListener(listener: Array[Byte] => Unit): Unit = {
51+
if (serialPort.isEmpty) throw new IllegalStateException("Serial port is not available yet")
6152
serialPortInputListener.addDataAvailableListener(_ => {
6253
val buffer = new Array[Byte](serialPort.get.bytesAvailable())
6354
serialPort.get.readBytes(buffer, buffer.length) //FIXME DOES IT CRASH?
@@ -69,12 +60,24 @@ class SerialConnector(override val sourceIdentifier: String) extends Connector(s
6960
* Opens a connection with the serial port
7061
*/
7162
override def start(): Boolean = {
63+
//TODO Test if connector is working this way or if it requires an actor
7264
try {
73-
serialPort = Some(SerialPort.getCommPort(sourceIdentifier))
65+
serialPort = Some(SerialPort.getCommPort(credentials.get.getValue("port").get))
66+
credentials.get.getValue("baudRate") match {
67+
case Some(baudRate) if baudRate.matches("\\s*\\d+\\s*") => serialPort.get.setBaudRate(baudRate.trim.toInt)
68+
case Some(ivalidBaudrate) =>
69+
logger error s"Invalid baud rate: $ivalidBaudrate"
70+
return false
71+
case None => //Do nothing
72+
}
73+
logger info s"Waiting for serial port to open..."
7474
if (serialPort.get.openPort(1000)) {
75+
Thread.sleep(1500)//Sleep to wait for
7576
serialPort.get.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0)
76-
out = Some(new PrintStream(serialPort.get.getOutputStream))
77+
out = Some(new PrintStream(serialPort.get.getOutputStream, true, "US-ASCII"))
78+
in = Some(serialPort.get.getInputStream)
7779
serialPort.get.addDataListener(serialPortInputListener)
80+
logger info "Opened serial port!"
7881
true
7982
} else {
8083
logger error s"Could not open serial port $sourceIdentifier"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.codeoverflow.chatoverflow.requirement.service.serial.impl
2+
3+
import java.io.InputStream
4+
import java.nio.charset.StandardCharsets
5+
import java.util.function.Consumer
6+
7+
import org.codeoverflow.chatoverflow.WithLogger
8+
import org.codeoverflow.chatoverflow.api.io.input.SerialInput
9+
import org.codeoverflow.chatoverflow.registry.Impl
10+
import org.codeoverflow.chatoverflow.requirement.InputImpl
11+
import org.codeoverflow.chatoverflow.requirement.service.serial.SerialConnector
12+
13+
import scala.collection.mutable.ListBuffer
14+
15+
@Impl(impl = classOf[SerialInput], connector = classOf[SerialConnector])
16+
class SerialInputImpl extends InputImpl[SerialConnector] with SerialInput with WithLogger {
17+
18+
private val stringListeners = ListBuffer[Consumer[String]]()
19+
private val byteListeners = ListBuffer[Consumer[Array[Byte]]]()
20+
21+
override def start(): Boolean = {
22+
sourceConnector.get.addInputListener(onIncomingData)
23+
true
24+
}
25+
26+
private def onIncomingData(bytes: Array[Byte]): Unit = {
27+
byteListeners.foreach(l => l.accept(bytes))
28+
stringListeners.foreach(l => l.accept(new String(bytes, StandardCharsets.US_ASCII)))
29+
}
30+
31+
override def registerStringListener(consumer: Consumer[String]): Unit = stringListeners += consumer
32+
33+
override def registerDataListener(consumer: Consumer[Array[Byte]]): Unit = byteListeners += consumer
34+
35+
override def getInputStream: InputStream = sourceConnector.get.getInputStream
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.codeoverflow.chatoverflow.requirement.service.serial.impl
2+
3+
import java.io.PrintStream
4+
5+
import org.codeoverflow.chatoverflow.WithLogger
6+
import org.codeoverflow.chatoverflow.api.io.output.SerialOutput
7+
import org.codeoverflow.chatoverflow.registry.Impl
8+
import org.codeoverflow.chatoverflow.requirement.OutputImpl
9+
import org.codeoverflow.chatoverflow.requirement.service.serial.SerialConnector
10+
11+
@Impl(impl = classOf[SerialOutput], connector = classOf[SerialConnector])
12+
class SerialOutputImpl extends OutputImpl[SerialConnector] with SerialOutput with WithLogger {
13+
14+
override def start(): Boolean = true
15+
16+
override def getPrintStream: PrintStream = sourceConnector.get.getPrintStream
17+
}

0 commit comments

Comments
 (0)