Skip to content
Snippets Groups Projects
Commit fae41545 authored by Lukas Friedrichsen's avatar Lukas Friedrichsen
Browse files

commented source code (gui view still pending)

parent c0a27e2c
No related branches found
No related tags found
No related merge requests found
Showing
with 158 additions and 57 deletions
/gui/
/server/
/common/
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -3,7 +3,7 @@ package common;
/*
* In dieser Klasse werden alle klassenübergreifen verwendeten Werte einmalig deklariert,
* so dass potentielle Änderungen lediglich einmalig an dieser Stelle durchgeführt werden
* müssen und Code-Vervielfachung vermieden wird.
* müssen und Code-Vervielfachung vermieden wird (Einhaltung des DRY-Prinzips).
*/
public class Properties {
......
......@@ -12,7 +12,7 @@ import javafx.beans.property.StringProperty;
import javafx.scene.image.Image;
/*
* Model class for a Model Engine
* Modell-Klasse für einen Zug.
*/
public class Engine {
......@@ -54,7 +54,7 @@ public class Engine {
return name;
}
// Returns the maerklin-id
// Returns the Maerklin-ID
public IntegerProperty getMaerklinID() {
return id;
}
......
......@@ -7,7 +7,7 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
/*
* Model class for a Model Engine
* Modell-Klasse für die Einstellungen der App.
*/
public class Settings {
private final ObjectProperty<InetSocketAddress> server;
......
......@@ -11,7 +11,7 @@ import javafx.beans.property.StringProperty;
import javafx.beans.property.ObjectProperty;
/*
* Model class for a Model Train Switch
* Modell-Klasse für eine Weiche.
*/
public class Switch{
......
......@@ -3,17 +3,24 @@ package server;
import java.util.ArrayList;
/*
* Diese Klasse stellt das Modell für einen Zug auf Serverseite dar.
* Weiterhin lassen sich über eine lokale Instanz des Maerklin-Protokolls
* Befehle an die Maerklin-C2-Steuerung senden.
*/
public class Engine {
// Static array containing all created instances of the object
static ArrayList<Engine> engines;
private int engineID;
int engineDirection;
int engineSpeed;
// Private locale instance of the maerklin-protocol to send commands to the control-station
private MaerklinProtocol udpProtocol;
private UDPListener listener;
// Constructor
public Engine(){
this(0, 1, 0);
......@@ -29,12 +36,12 @@ public class Engine {
engineSpeed = 0;*/
}
// Constructor with some initial data
public Engine(int id, int direction, int speed){
if (engines == null) {
engines = new ArrayList<Engine>();
}
udpProtocol = new MaerklinProtocol();
listener = new UDPListener();
engines.add(this);
try {
setEngineID(id);
......@@ -46,10 +53,12 @@ public class Engine {
}
}
// Sets the Maerklin-ID
public void setEngineID(int newID){
engineID = newID;
}
// Sets the engine-direction and sends the respective command to the control-station; a 3 as the direction-parameter causes a switch of the direction
public void setEngineDirection(int newEngineDirection) throws Exception {
if (newEngineDirection == 1 || newEngineDirection == 2){
engineDirection = newEngineDirection;
......@@ -69,6 +78,8 @@ public class Engine {
udpProtocol.changeEngineDirection(engineID, engineDirection);
}
// Sets the engine-speed and sends the respective command to the control-station
public void setEngineSpeed(int newEngineSpeed) throws Exception {
if (newEngineSpeed <= 1000 && newEngineSpeed >= 0){
engineSpeed = newEngineSpeed;
......@@ -80,24 +91,29 @@ public class Engine {
udpProtocol.changeEngineSpeed(engineID, engineSpeed);
}
// Increases the engine-speed by 50 and calls changeEngineSpeed with the new speed-value
public void increaseEngineSpeed() throws Exception {
engineSpeed = engineSpeed+50;
udpProtocol.changeEngineSpeed(engineID, engineSpeed);
}
// Decreases the engine-speed by 50 and calls changeEngineSpeed with the new speed-value
public void decreaseEngineSpeed() throws Exception{
engineSpeed = engineSpeed-50;
udpProtocol.changeEngineSpeed(engineID, engineSpeed);
}
// Returns the Maerklin-ID
public int getEngineID(){
return engineID;
}
// Returns the engine-direction
public int getEngineDirection(){
return engineDirection;
}
// Returns the engine-speed
public int getEngineSpeed(){
return engineSpeed;
}
......
......@@ -2,15 +2,25 @@ package server;
import java.net.*;
/*
* Diese Klasse implementiert das Maerklin-Protokoll zur Kommunikation
* mit der Maerklin-C2-Steuerung. Die Datagramme werden mittels UDP
* gesendet; für jedes Datagram wird ein neuer Sockel geöffnet.
*/
public class MaerklinProtocol {
// Setting the input-port of the maerklin-control-station
private final static int port = 15731;
// IP of the maerklin-control-station
private final static String ip ="192.168.74.118";
// Constructor
public MaerklinProtocol(){
//Nothing to do...
}
// Tries to open a UDP-socket and send the datagram to the maerklin-control-station
private void writeDatagram(String ip, int port, byte[] data){
//System.out.printf("\nGesendet: " + DatatypeConverter.printHexBinary(data));
try(DatagramSocket socket = new DatagramSocket()){
......@@ -24,16 +34,19 @@ public class MaerklinProtocol {
}
}
// Resets the emergency-stop (re-enables power)
public void systemGo(){
byte[] out = {(byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x78, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00};
this.writeDatagram(ip, port, out);
}
// Emergency-stop (cuts the power)
public void systemStop(){
byte[] out = {(byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x78, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
this.writeDatagram(ip, port, out);
}
// Set engine-speed of the given engine to the given value
public void changeEngineSpeed(int mfxAddress, int newEngineSpeed){
byte[] engineSpeed = {(byte) Math.floor(newEngineSpeed/256), (byte) Math.floor(newEngineSpeed%256)};
byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)};
......@@ -41,6 +54,7 @@ public class MaerklinProtocol {
this.writeDatagram(ip, port, out);
}
// Set engine-direction of the given engine to the given value
public void changeEngineDirection(int mfxAddress, int newEngineDirection){
byte engineDirection = (byte) Math.floor(newEngineDirection%256);
byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)};
......@@ -48,6 +62,7 @@ public class MaerklinProtocol {
this.writeDatagram(ip, port, out);
}
// Set the switch-direction of the given switch to the given value or move the turntable clockwise or counterclockwise
public void changeSwitchDirection(int mfxAddress, int newSwitchDirection){
byte switchDirection = (byte) Math.floor(newSwitchDirection%256);
byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)};
......
......@@ -14,19 +14,33 @@ import javax.xml.bind.DatatypeConverter;
import common.Properties;
/*
* MaerklinServer stellt die Hauptklasse des Servers dar. Alle verwendeten
* Objekte und Services (bspw. Executer-Services) werden initialisiert und
* der Server-Thread wird gestartet. Weiterhin implementiert diese Klasse
* das Maerklin-Protokoll und dient damit für alle anderen abgeleiteten oder
* erzeugten Objekte als Referenz für die Kommunikation mit dem Server.
* Grundlegende Funktionen wie der Notaus werden direkt von dieser Klasse
* umgesetzt.
*/
public class MaerklinServer{
// Declaration of objects
// List to monitor the registered clients
ArrayList<Socket> clients;
// Control-elements and thread to handle new clients
private MaerklinProtocol protocol;
private UDPListener overwatch;
private ServerThread serverThread;
// Executor-services to handle the threads
final ExecutorService SERVER_THREAD_EXECUTOR;
final ExecutorService CLIENT_THREAD_EXECUTOR;
final ExecutorService UTILITY_THREAD_EXECUTOR;
// Accessories
private Engine ice;
private Engine lok;
private Engine reichsbahn;
......@@ -43,6 +57,7 @@ public class MaerklinServer{
private Switch switch15;
private Switch turntable;
// Constructor
public MaerklinServer(){
// Initializing
......@@ -54,9 +69,9 @@ public class MaerklinServer{
overwatch = new UDPListener();
serverThread = new ServerThread(this);
SERVER_THREAD_EXECUTOR = Executors.newFixedThreadPool(2);
CLIENT_THREAD_EXECUTOR = Executors.newCachedThreadPool();
UTILITY_THREAD_EXECUTOR = Executors.newCachedThreadPool();
SERVER_THREAD_EXECUTOR = Executors.newFixedThreadPool(2); // Server- and listener-thread
CLIENT_THREAD_EXECUTOR = Executors.newCachedThreadPool(); // Client-threads
UTILITY_THREAD_EXECUTOR = Executors.newCachedThreadPool(); // Handle- and update-threads
ice = new Engine();
lok = new Engine();
......@@ -102,7 +117,7 @@ public class MaerklinServer{
}
}
// Emergency stop
// Emergency stop; sets the speed of all engines to 0 out of safety reasons
public void emergencyStop() throws Exception {
protocol.systemStop();
ice.setEngineSpeed(0);
......@@ -110,12 +125,12 @@ public class MaerklinServer{
reichsbahn.setEngineSpeed(0);
}
// Emergency stop
// Resets emergency stop
public void start() throws Exception {
protocol.systemGo();
}
// Initialize; setting ("safe") values
// Initialize; setting ("safe") values (engine speed to 0 and switch direction to straight)
public void initialize() throws Exception {
ice.setEngineDirection(1);
ice.setEngineSpeed(0);
......@@ -148,11 +163,10 @@ public class MaerklinServer{
SERVER_THREAD_EXECUTOR.submit(serverThread);
}
// Starts the thread to broadcast the current status
// Starts a thread to broadcast the current status for every registered client
public void statusUpdate(){
for (Socket clientSocket : clients) {
try {
//System.out.println("Updating client: "+clientSocket.getRemoteSocketAddress());
UTILITY_THREAD_EXECUTOR.submit(new UpdateThread(clientSocket.getOutputStream()));
}
catch (IOException e) {
......@@ -163,10 +177,15 @@ public class MaerklinServer{
}
//Opens a server-port and establishes a new handling-thread for every client that connects to the server
/*
* Diese Klasse öffnet einen Server-Port und erstellt einen neue Client-Thread-Instanz
* für jeden Client, der sich neu an dem Server anmeldet.
*/
class ServerThread implements Runnable {
// Declaration of objects
// Instance of the server; serves to solve references
private final MaerklinServer SERVER_INSTANCE;
// Constructor
......@@ -174,6 +193,7 @@ class ServerThread implements Runnable {
SERVER_INSTANCE = server;
}
// Waits for clients to connect and submits a new client-thread afterwards
@Override
public void run() {
try(ServerSocket serverSocket = new ServerSocket(Properties.PORT)){
......@@ -190,6 +210,7 @@ class ServerThread implements Runnable {
run();
}
finally {
// Properly shuts down all running threads if the server is closed
SERVER_INSTANCE.SERVER_THREAD_EXECUTOR.shutdownNow();
SERVER_INSTANCE.CLIENT_THREAD_EXECUTOR.shutdownNow();
SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.shutdownNow();
......@@ -198,13 +219,23 @@ class ServerThread implements Runnable {
}
// Handles the communication with the clients in the background
/*
* Die Klasse ClientThread verwaltet die Kommunikation mit dem Client
* im Hintergrund und öffnet bei eingehenden Befehlen einen neuen Handling-Thread.
*/
class ClientThread implements Runnable {
// Declaration of objects
// Instance of the server; serves to solve references
private final MaerklinServer SERVER_INSTANCE;
// Instance of the client-socket; serves to solve references
private final Socket CLIENT;
// Wrapper for the client-sockets' input-stream to buffer the incoming data
private final BufferedInputStream IN_STREAM;
private final MaerklinServer SERVER_INSTANCE;
byte[] data;
// Constructor
......@@ -216,40 +247,42 @@ class ClientThread implements Runnable {
data = new byte[Properties.IN_BUFFER_SIZE];
}
// Checks if the client sends a session-abort-message passes client-requests to a handle-thread
@Override
public void run() {
int buffer;
while (true) {
try {
if (IN_STREAM.available() != 0) {
buffer = IN_STREAM.read();
if ((byte) buffer == (byte) Properties.SESSION_ABORT) {
buffer = IN_STREAM.read(); // Reads one byte from the input-stream
if ((byte) buffer == (byte) Properties.SESSION_ABORT) { // Checks for a session-abort signal and potentially severs the connection potentially
SERVER_INSTANCE.clients.remove(CLIENT);
CLIENT.close();
System.out.println("Conenction to client "+CLIENT.getRemoteSocketAddress()+" aborted!");
return;
}
else if ((byte) buffer == (byte) Properties.SEPERATOR) {
for (int i = 0; i < Properties.IN_BUFFER_SIZE; i++) {
else if ((byte) buffer == (byte) Properties.SEPERATOR) { // Checks for the beginning of a new datagram (all datagrams begin with a seperator-byte to mark their start)
for (int i = 0; i < Properties.IN_BUFFER_SIZE; i++) { // Tries to read the whole datagram
buffer = IN_STREAM.read();
if ((byte) buffer == (byte) Properties.SESSION_ABORT) {
if ((byte) buffer == (byte) Properties.SESSION_ABORT) { // Again checks for a session-abort signal from the client
SERVER_INSTANCE.clients.remove(CLIENT);
CLIENT.close();
System.out.println("Connection to client "+CLIENT.getRemoteSocketAddress()+" aborted!");
return;
}
else {
data[i] = (byte) (buffer%(1<<8));
data[i] = (byte) (buffer%(1<<8)); // Typecast to byte through bitshift
}
}
SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.submit(new HandleThread(SERVER_INSTANCE, data));
SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.submit(new HandleThread(SERVER_INSTANCE, data)); // Submits a new handle-thread for the datagram
}
}
else {
Thread.sleep(10);
Thread.sleep(10); // Frees the resources until the next check
}
}
catch (Exception e) {
// Unregister the client if an error occurers
System.out.println("An error occured while reading the clients input-stream!");
SERVER_INSTANCE.clients.remove(CLIENT);
System.out.println("Conenction to client "+CLIENT.getRemoteSocketAddress()+" aborted!");
......@@ -260,11 +293,19 @@ class ClientThread implements Runnable {
}
// Processes the incoming datagram and initializes appropriate actions
/*
* HandleThread verarbeitet Anfragen von den Clients und initiiert entsprechende Aktionen.
* Format des Datagrams: 1.+2. Byte: Maerklin-ID
* 3. Byte: Befehl
* 4.+5. Byte: potentielle Parameter
*/
class HandleThread implements Runnable {
// Declaration of objects
// Declaration of objects// Declaration of objects
// Instance of the server; serves to solve references
private final MaerklinServer SERVER_INSTANCE;
byte[] data;
// Constructor
......@@ -273,23 +314,24 @@ class HandleThread implements Runnable {
data = incomingData;
}
// Reads the command and initiates the according action
@Override
public void run() {
try {
switch (data[2]) {
case Properties.SYSTEM_STOP:
switch (data[2]) { // Compare the command-byte to the values set in Properties
case Properties.SYSTEM_STOP: // Emergency-stop (cuts the power)
//System.out.println("System stop");
SERVER_INSTANCE.emergencyStop();
break;
case Properties.SYSTEM_GO:
case Properties.SYSTEM_GO: // Resets the emergency-stop (re-enables power)
//System.out.println("System go");
SERVER_INSTANCE.start();
break;
case Properties.GET_STATUS:
case Properties.GET_STATUS: // Status-update
//System.out.println("Status update");
SERVER_INSTANCE.statusUpdate();
break;
case Properties.ENGINE_SET_SPEED:
case Properties.ENGINE_SET_SPEED: // Set engine-speed to the given value
for (Engine train : Engine.engines) {
if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Set engine speed");
......@@ -298,7 +340,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.ENGINE_INCREASE_SPEED:
case Properties.ENGINE_INCREASE_SPEED: // Increase the engine-speed by 50
for (Engine train : Engine.engines) {
if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Increase engine speed");
......@@ -307,7 +349,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.ENGINE_DECREASE_SPEED:
case Properties.ENGINE_DECREASE_SPEED: // Decrease the engine-speed by 50
for (Engine train : Engine.engines) {
if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Decrease engine speed");
......@@ -316,7 +358,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.ENGINE_SET_DIRECTION:
case Properties.ENGINE_SET_DIRECTION: // Set engine-direction to the given value
for (Engine train : Engine.engines) {
if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Set engine direction");
......@@ -325,7 +367,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.ENGINE_SWITCH_DIRECTION:
case Properties.ENGINE_SWITCH_DIRECTION: // Switch the engine-direction
for (Engine train : Engine.engines) {
if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Switch engine direction");
......@@ -334,7 +376,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.SWITCH_SET_DIRECTION:
case Properties.SWITCH_SET_DIRECTION: // Set the switch-direction to the given value or move the turntable clockwise or counterclockwise
for (Switch sw : Switch.switches) {
if (sw.getSwitchID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Set switch direction");
......@@ -343,7 +385,7 @@ class HandleThread implements Runnable {
}
}
break;
case Properties.SWITCH_SWITCH_DIRECTION:
case Properties.SWITCH_SWITCH_DIRECTION: // Switch the switch-direction
for (Switch sw : Switch.switches) {
if (sw.getSwitchID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) {
//System.out.println("Switch switch direction");
......@@ -352,7 +394,7 @@ class HandleThread implements Runnable {
}
}
break;
default:
default: // Command doesn't match any of the cases
System.out.println("No viable command!\n");
}
}
......@@ -363,11 +405,19 @@ class HandleThread implements Runnable {
}
//Broadcasts the current status
/*
* Diese Klasse konvertiert bei Aufruf den aktuellen Status der (serverseitigen)
* Modelle in Byte-Format und wandelt diese unter Hinzufügen von Start- End- und
* Trenn-Bytes in ein Datagram um, dass an den Client gesendet wird.
*/
class UpdateThread implements Runnable {
// Declaration of objects
// Output-stream of the client handled by the thread
private final OutputStream OUT_STREAM;
// Buffer for the datagram
private byte[] outgoingData;
// Constructor
......@@ -376,30 +426,30 @@ class UpdateThread implements Runnable {
// Setting the broadcast-port
OUT_STREAM = out;
// Initializing
// Initializing the buffer-array to the size of the datagram
outgoingData = new byte[Properties.OUT_BUFFER_SIZE];
}
// Reads every registered objects data into outgoingData and broadcasts the status
// Reads every registered objects data into outgoingData and sends the status
@Override
public void run() {
int position = 0;
try {
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR; // Start-bytes
outgoingData[position++] = Properties.SEPERATOR;
for (Engine train : Engine.engines) {
if (position >= Properties.OUT_BUFFER_SIZE-9) {
Exception e = new Exception("Overload of registered elements! Update-buffer too small!");
throw e;
}
outgoingData[position++] = (byte) ((train.getEngineID()/(1<<8))%(1<<8));
outgoingData[position++] = (byte) ((train.getEngineID()/(1<<8))%(1<<8)); // Maerklin-ID
outgoingData[position++] = (byte) ((train.getEngineID()%(1<<8)));
outgoingData[position++] = (byte) ((train.getEngineSpeed()/(1<<8))%(1<<8));
outgoingData[position++] = (byte) ((train.getEngineSpeed()/(1<<8))%(1<<8)); // Speed
outgoingData[position++] = (byte) ((train.getEngineSpeed()%(1<<8)));
outgoingData[position++] = (byte) ((train.getEngineDirection()%(1<<24)));
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = (byte) ((train.getEngineDirection()%(1<<24))); // Direction
outgoingData[position++] = Properties.SEPERATOR; // Separator-byte between the engines
}
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR; // Separator-bytes between the engines and the switches
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR;
for (Switch sw : Switch.switches) {
......@@ -407,14 +457,14 @@ class UpdateThread implements Runnable {
Exception e = new Exception("Overload of registered elements! Update-buffer too small!");
throw e;
}
outgoingData[position++] = (byte) ((sw.getSwitchID()/(1<<8))%(1<<8));
outgoingData[position++] = (byte) ((sw.getSwitchID()/(1<<8))%(1<<8)); // Maerklin-ID
outgoingData[position++] = (byte) ((sw.getSwitchID()%(1<<8)));
outgoingData[position++] = (byte) 0x00; // Inserted two null-bytes to match the engines-format
outgoingData[position++] = (byte) 0x00;
outgoingData[position++] = (byte) 0x00;
outgoingData[position++] = (byte) ((sw.getSwitchDirection()%(1<<24)));
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = (byte) ((sw.getSwitchDirection()%(1<<24))); // Direction
outgoingData[position++] = Properties.SEPERATOR; // Separator-byte between the switches
}
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR; // Stop-bytes
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR;
outgoingData[position++] = Properties.SEPERATOR;
......@@ -425,7 +475,7 @@ class UpdateThread implements Runnable {
}
//System.out.printf("\nSende: " + DatatypeConverter.printHexBinary(outgoingData));
try {
OUT_STREAM.write(outgoingData, 0, Properties.OUT_BUFFER_SIZE);
OUT_STREAM.write(outgoingData, 0, Properties.OUT_BUFFER_SIZE); // Send the datagram to the client
}
catch (Exception e) {
System.out.println("Communication-error whilst status-update!");
......
package server;
/*
* MaerklinServerApplication startet den Server sowie den Listener, der
* die serverseitigen Modelle aktualisiert. Weiterhin initialisiert die Klasse
* zyklisch ein synchrones Status-Update für alle registrierten Clients.
*/
public class MaerklinServerApplication {
// Defining a threshold value for when the status-update is to be executed (in milliseconds)
......@@ -19,6 +25,7 @@ public class MaerklinServerApplication {
// Starting the client-handling
server.listen();
// Periodically checks if the update-threshold has been exceeded and potentially initializes the status update through statusUpdate
while (true){
if (System.currentTimeMillis()-timestamp >= updateThreshold) {
server.statusUpdate();
......
......@@ -2,16 +2,23 @@ package server;
import java.util.ArrayList;
/*
* Diese Klasse stellt das Modell für eine Weiche auf Serverseite dar.
* Weiterhin lassen sich über eine lokale Instanz des Maerklin-Protokolls
* Befehle an die Maerklin-C2-Steuerung senden.
*/
public class Switch {
// Static array containing all created instances of the object
static ArrayList<Switch> switches;
private int switchID;
int switchDirection;
// Private locale instance of the maerklin-protocol to send commands to the control-station
private MaerklinProtocol udpProtocol;
private UDPListener listener;
// Constructor
public Switch(){
this(0, 1);
......@@ -26,12 +33,12 @@ public class Switch {
switchDirection = 1;*/
}
// Constructor with some initial data
public Switch(int id, int direction){
if (switches == null) {
switches = new ArrayList<Switch>();
}
udpProtocol = new MaerklinProtocol();
listener = new UDPListener();
switches.add(this);
try {
setSwitchID(id);
......@@ -42,10 +49,12 @@ public class Switch {
}
}
// Sets the Maerklin-ID
public void setSwitchID(int newSwitchID){
switchID = newSwitchID;
}
// Sets the switch-direction and sends the respective command to the control-station
public void setSwitchDirection(int newSwitchDirection) throws Exception {
if (newSwitchDirection == 0x01 || newSwitchDirection == 0x00){
switchDirection = newSwitchDirection;
......@@ -57,6 +66,7 @@ public class Switch {
udpProtocol.changeSwitchDirection(switchID, switchDirection);
}
// Changes the switch-direction and calls setSwitchDirection with the new vdirection-alue
public void changeSwitchDirection() throws Exception {
if (switchDirection == 0x00){
setSwitchDirection(0x01);
......@@ -66,10 +76,12 @@ public class Switch {
}
}
// Returns the Maerklin-ID
public int getSwitchID(){
return switchID;
}
// Returns the switch-direction
public int getSwitchDirection(){
return switchDirection;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment