Skip to content

Commit

Permalink
Large refactoring:
Browse files Browse the repository at this point in the history
Documentation
Split Classes in own files
package structure
removed unnecessary imports
  • Loading branch information
diekmann committed Feb 19, 2013
1 parent a2b0966 commit ac2f5b3
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 117 deletions.
2 changes: 1 addition & 1 deletion otherdevices.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<bacdevices>
<device cname="SensorSink">192.168.56.101</device>
<device cname="SensorSink">192.168.56.20</device>
<device cname="SensorSink">192.168.56.102</device>
</bacdevices>
108 changes: 1 addition & 107 deletions src/main/scala/tum/in/net/bacnet/MyMain.scala
Original file line number Diff line number Diff line change
@@ -1,115 +1,9 @@
package tum.in.net.bacnet

import tum.in.net.bacnet.deviceFactory.{MySlaveDevice, MyReader, MyReaderWriterActiveMasterSlaveDevice}

import com.serotonin.bacnet4j._
import com.serotonin.bacnet4j.`type`.constructed._
import com.serotonin.bacnet4j.`type`.primitive
import com.serotonin.bacnet4j.`type`.enumerated._
import com.serotonin.bacnet4j.`type`.notificationParameters._
import com.serotonin.bacnet4j.`type`.Encodable
import com.serotonin.bacnet4j.service.confirmed.ReinitializeDeviceRequest._
import com.serotonin.bacnet4j.obj._


class MyReader(val localDevice: MyLocalDevice = new MyLocalDevice(
broadcastAddress = "127.0.0.255",
name = "corny's reader",
deviceId=1234), abortOnNoRemotes: Boolean = true){

def readConfigFromXML(file: java.io.File): List[String] = {
println("reading configuration file "+file)
val knownDevicesFromConfig = scala.io.Source.fromFile(file)
val otherDevicesString: String = try {
knownDevicesFromConfig.mkString
} finally {
knownDevicesFromConfig.close()
}
import scala.xml._
require(!otherDevicesString.isEmpty())

// config template
// val xmlOtherDevices = <bacdevices>
// <device>192.168.56.102</device>
// <device>192.168.56.103</device>
// <device>192.168.56.104</device>
// </bacdevices>

val xmlOtherDevices = XML.loadString(otherDevicesString)
assert(xmlOtherDevices.isInstanceOf[scala.xml.Elem])
val deviceIPs: NodeSeq = (xmlOtherDevices \\ "bacdevices")
try{
assert(!deviceIPs.isEmpty)
} catch {
case e: java.lang.AssertionError =>
println("Error: "+e)
if (abortOnNoRemotes)
throw e
else
println("continue")
}
val deviceIPsList: List[String] = (for (node <- (deviceIPs \\ "device"))yield node.text).toList
println("parsed devices from config: "+deviceIPsList)
deviceIPsList
}

val otherDevices: List[String] = readConfigFromXML(new java.io.File("otherdevices.xml"))


val localReader = new SlaveDeviceReading(localDevice=localDevice,
otherDevices=otherDevices,
abortOnNoRemotes=abortOnNoRemotes)

def start(initLocalDevice: Boolean = true) = {
if (initLocalDevice){
localDevice.initialize()
}
localReader.start()
// TODO
// we could pass abortOnNoRemotes=true and catch the assertion error, if no remote devices are found
// retry every X seconds
// although, this is better done in the SlaveDeviceReading's act method act
}
}

class MyReaderWriterActiveMasterSlaveDevice{

val hostname: String = try {
java.net.InetAddress.getLocalHost.getHostName
}catch{
case e: java.net.UnknownHostException =>
println("Error: "+e)
val hostnameguess_array = e.toString().split(' ')
if (hostnameguess_array.length < 2){
null
}

val hostnameguess = hostnameguess_array(hostnameguess_array.length - 1)
if (hostnameguess.length() >= 5){
println("guessing hostname `"+hostnameguess+"'")
hostnameguess
} else {
null
}
}

/* acts, changes values */
val localSlaveDevice = new MySlaveDevice(
broadcastAddress = "127.0.0.255",
name=hostname,
randomValues=true)

val localDevice = localSlaveDevice.localDevice

val localReader = new MyReader(localDevice, abortOnNoRemotes=false)


def start() = {
localSlaveDevice.start()
localReader.start(initLocalDevice=false)
}

}

object MyMain {

def slave(): Unit = {
Expand Down
116 changes: 116 additions & 0 deletions src/main/scala/tum/in/net/bacnet/deviceFactory/MyBACnetDevices.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package tum.in.net.bacnet.deviceFactory


import tum.in.net.bacnet.lowlevel.device.MyLocalDevice
import tum.in.net.bacnet.lowlevel.SlaveDeviceReading


/**
* reads an xml file with other known BACnet devices
* queries and sets their values
* supervisory device
*/
class MyReader(val localDevice: MyLocalDevice = new MyLocalDevice(
broadcastAddress = "127.0.0.255",
name = "corny's reader",
deviceId=1234), abortOnNoRemotes: Boolean = true){

def readConfigFromXML(file: java.io.File): List[String] = {
println("reading configuration file "+file)
val knownDevicesFromConfig = scala.io.Source.fromFile(file)
val otherDevicesString: String = try {
knownDevicesFromConfig.mkString
} finally {
knownDevicesFromConfig.close()
}
import scala.xml._
require(!otherDevicesString.isEmpty())

// config template
// val xmlOtherDevices = <bacdevices>
// <device>192.168.56.102</device>
// <device>192.168.56.103</device>
// <device>192.168.56.104</device>
// </bacdevices>

val xmlOtherDevices = XML.loadString(otherDevicesString)
assert(xmlOtherDevices.isInstanceOf[scala.xml.Elem])
val deviceIPs: NodeSeq = (xmlOtherDevices \\ "bacdevices")
try{
assert(!deviceIPs.isEmpty)
} catch {
case e: java.lang.AssertionError =>
println("Error: "+e)
if (abortOnNoRemotes)
throw e
else
println("continue")
}
val deviceIPsList: List[String] = (for (node <- (deviceIPs \\ "device"))yield node.text).toList
println("parsed devices from config: "+deviceIPsList)
deviceIPsList
}

val otherDevices: List[String] = readConfigFromXML(new java.io.File("otherdevices.xml"))


val localReader = new SlaveDeviceReading(localDevice=localDevice,
otherDevices=otherDevices,
abortOnNoRemotes=abortOnNoRemotes)

def start(initLocalDevice: Boolean = true) = {
if (initLocalDevice){
localDevice.initialize()
}
localReader.start()
// TODO
// we could pass abortOnNoRemotes=true and catch the assertion error, if no remote devices are found
// retry every X seconds
// although, this is better done in the SlaveDeviceReading's act method act
}
}


/**
* reads an xml file with other known BACnet devices
* queries and sets their values
* Also is an active BACnet device with changing Input/Output values
*/
class MyReaderWriterActiveMasterSlaveDevice{

val hostname: String = try {
java.net.InetAddress.getLocalHost.getHostName
}catch{
case e: java.net.UnknownHostException =>
println("Error: "+e)
val hostnameguess_array = e.toString().split(' ')
if (hostnameguess_array.length < 2){
null
}

val hostnameguess = hostnameguess_array(hostnameguess_array.length - 1)
if (hostnameguess.length() >= 5){
println("guessing hostname `"+hostnameguess+"'")
hostnameguess
} else {
null
}
}

/* acts, changes values */
val localSlaveDevice = new MySlaveDevice(
broadcastAddress = "127.0.0.255",
name=hostname,
randomValues=true)

val localDevice = localSlaveDevice.localDevice

val localReader = new MyReader(localDevice, abortOnNoRemotes=false)


def start() = {
localSlaveDevice.start()
localReader.start(initLocalDevice=false)
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
package tum.in.net.bacnet
package tum.in.net.bacnet.deviceFactory

import com.serotonin.bacnet4j.`type`.enumerated._
import com.serotonin.bacnet4j.LocalDevice
import tum.in.net.bacnet.lowlevel.device.MyLocalDevice
import tum.in.net.bacnet.lowlevel.SlaveDeviceIO
import tum.in.net.bacnet.lowlevel.IOTypeOutput
import tum.in.net.bacnet.lowlevel.IOTypeInput
import tum.in.net.bacnet.lowlevel.IOType


/**
* Generic Class to instantiate a BACnet device
* with I/O
* @author corny
*
*/
class MySlaveDevice(broadcastAddress: String, name: String = null, randomValues: Boolean = false)
{
val random = if (randomValues) new scala.util.Random() else null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package tum.in.net.bacnet
package tum.in.net.bacnet.lowlevel

import com.serotonin.bacnet4j._
import com.serotonin.bacnet4j.`type`.constructed._
import com.serotonin.bacnet4j.`type`.primitive
import com.serotonin.bacnet4j.`type`.enumerated._
import com.serotonin.bacnet4j.`type`.notificationParameters._
import com.serotonin.bacnet4j.`type`.Encodable
import com.serotonin.bacnet4j.service.confirmed.ReinitializeDeviceRequest._
import com.serotonin.bacnet4j.obj._

import scala.actors.Actor
import scala.actors.Actor._
import tum.in.net.bacnet.lowlevel.device.MyLocalDevice

abstract sealed class IOType
case object IOTypeInput extends IOType
case object IOTypeOutput extends IOType


/**
* Add to BACnet device `localDevice` Input/Ouput values
* @author corny
*
*/
class SlaveDeviceIO(
val localDevice: MyLocalDevice,
ConfiguredAnalogueIO: List[(IOType, String, EngineeringUnits)],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tum.in.net.bacnet
package tum.in.net.bacnet.lowlevel

import com.serotonin.bacnet4j._
import com.serotonin.bacnet4j.`type`.constructed._
Expand All @@ -11,7 +11,19 @@ import com.serotonin.bacnet4j.obj._
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.TIMEOUT
import tum.in.net.bacnet.lowlevel.device.BACListeneriAmReceived
import tum.in.net.bacnet.lowlevel.device.MyLocalDevice
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.JavaConversions.iterableAsScalaIterable
import scala.collection.JavaConversions.mapAsScalaMap
import scala.collection.JavaConversions.seqAsJavaList

/**
* Add to BACnet device `localDevice` more features
* Read/write/query values from other BACnet devices
* @author corny
*
*/
class SlaveDeviceReading (
val localDevice: MyLocalDevice,
val otherDevices: List[String],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tum.in.net.bacnet
package tum.in.net.bacnet.lowlevel.device

import com.serotonin.bacnet4j._
import com.serotonin.bacnet4j.`type`.constructed._
Expand All @@ -10,7 +10,6 @@ import com.serotonin.bacnet4j.service.confirmed.ReinitializeDeviceRequest._
import com.serotonin.bacnet4j.obj._



abstract sealed trait BACListenerMessage
case class BACListeneriAmReceived(d: RemoteDevice) extends BACListenerMessage

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tum.in.net.bacnet
package tum.in.net.bacnet.lowlevel.device


import com.serotonin.bacnet4j._
Expand All @@ -9,7 +9,16 @@ import com.serotonin.bacnet4j.`type`.notificationParameters._
import com.serotonin.bacnet4j.`type`.Encodable
import com.serotonin.bacnet4j.service.confirmed.ReinitializeDeviceRequest._
import com.serotonin.bacnet4j.obj._
import scala.Array.canBuildFrom
import scala.collection.JavaConversions.asScalaBuffer


/**
* My local BACnet device
* Other classes in the lowlevel package extend its functionality
* @author corny
*
*/
class MyLocalDevice(val broadcastAddress: String,
val name: String,
val deviceId: Int, // make sure this value is unique!
Expand Down

0 comments on commit ac2f5b3

Please sign in to comment.