diff --git a/.classpath b/.classpath
index 899de31..d88872f 100644
--- a/.classpath
+++ b/.classpath
@@ -6,18 +6,13 @@
+
+
-
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index b80a7fe..45a2556 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.5.4
+ 0.5.5
Web4Rail
Java Model Railway Control
https://github.com/StephanRichter/Web4Rail
@@ -33,7 +33,7 @@
de.srsoftware
tools
- 1.1.8
+ 1.1.9
compile
diff --git a/resources/logback.xml b/resources/logback.xml
new file mode 100644
index 0000000..c22c8ca
--- /dev/null
+++ b/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java
index bbbb58c..f95fe36 100644
--- a/src/main/java/de/srsoftware/web4rail/Application.java
+++ b/src/main/java/de/srsoftware/web4rail/Application.java
@@ -10,6 +10,8 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -30,7 +32,7 @@ public class Application {
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
private static final String PORT = "port";
private static final Charset UTF8 = StandardCharsets.UTF_8;
-
+
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Configuration config = new Configuration(Configuration.dir("Web4Rail")+"/app.config");
LOG.debug("Config: {}",config);
diff --git a/src/main/java/de/srsoftware/web4rail/ControlUnit.java b/src/main/java/de/srsoftware/web4rail/ControlUnit.java
index b5c489d..1ef016c 100644
--- a/src/main/java/de/srsoftware/web4rail/ControlUnit.java
+++ b/src/main/java/de/srsoftware/web4rail/ControlUnit.java
@@ -45,7 +45,7 @@ public class ControlUnit extends Thread{
milis = Integer.parseInt(word.substring(word.length()-3));
code = scanner.nextInt();
message = scanner.nextLine().trim();
- LOG.debug("recv {}.{} {} {}.",secs,milis,code,message);
+ LOG.info("recv {}.{} {} {}.",secs,milis,code,message);
}
@Override
@@ -211,7 +211,7 @@ public class ControlUnit extends Thread{
private void writeln(String data) throws IOException {
data = data.replace("{}", ""+bus);
socket.getOutputStream().write((data+"\n").getBytes(StandardCharsets.US_ASCII));
- LOG.debug("sent {}.",data);
+ LOG.info("sent {}.",data);
}
public void update(HashMap params) {
diff --git a/src/main/java/de/srsoftware/web4rail/Device.java b/src/main/java/de/srsoftware/web4rail/Device.java
new file mode 100644
index 0000000..884d756
--- /dev/null
+++ b/src/main/java/de/srsoftware/web4rail/Device.java
@@ -0,0 +1,7 @@
+package de.srsoftware.web4rail;
+
+public interface Device {
+ public static final String ADDRESS = "address";
+ public static final String PORT = "port";
+ public static final String PROTOCOL = "proto";
+}
diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java
index fb4e60d..2d2b525 100644
--- a/src/main/java/de/srsoftware/web4rail/Plan.java
+++ b/src/main/java/de/srsoftware/web4rail/Plan.java
@@ -299,11 +299,15 @@ public class Plan {
LOG.warn("Was not able to load routes!",e);
}
try {
- plan.controlUnit.load(filename+".cu");
- plan.controlUnit.start();
+ plan.controlUnit.load(filename+".cu");
} catch (Exception e) {
LOG.warn("Was not able to load control unit settings!",e);
}
+ try {
+ plan.controlUnit.start();
+ } catch (Exception e) {
+ LOG.warn("Was not able to establish connection to control unit!");
+ }
return plan;
}
diff --git a/src/main/java/de/srsoftware/web4rail/Protocol.java b/src/main/java/de/srsoftware/web4rail/Protocol.java
new file mode 100644
index 0000000..a7f934b
--- /dev/null
+++ b/src/main/java/de/srsoftware/web4rail/Protocol.java
@@ -0,0 +1,12 @@
+package de.srsoftware.web4rail;
+
+public enum Protocol{
+ DCC14,
+ DCC27,
+ DCC28,
+ DCC128,
+ MOTO,
+ FLEISCH,
+ SELECTRIX,
+ ZIMO;
+}
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java
index a3ced8c..e7d3668 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java
@@ -6,7 +6,9 @@ import java.util.Vector;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.Device;
import de.srsoftware.web4rail.Plan;
+import de.srsoftware.web4rail.Protocol;
import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Fieldset;
@@ -15,16 +17,10 @@ import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Radio;
-public class Locomotive extends Car {
-
- public enum Protocol{
- DCC14,DCC27,DCC28,DCC128,MOTO,FLEISCH,SELECTRIX,ZIMO;
- }
+public class Locomotive extends Car implements Device{
private static final String REVERSE = "reverse";
public static final String LOCOMOTIVE = "locomotive";
- private static final String PROTOCOL = "protocol";
- private static final String ADDRESS = "address";
private boolean reverse = false;
private Protocol proto = Protocol.DCC128;
private int address = 3;
diff --git a/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java b/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java
index 53ae9f7..fcd5303 100644
--- a/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java
+++ b/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java
@@ -5,9 +5,10 @@ import de.srsoftware.tools.Tag;
public class Fieldset extends Tag {
private static final long serialVersionUID = -1643025934527173421L;
+ public static final String TYPE = "fieldset";
public Fieldset(String title) {
- super("fieldset");
+ super(TYPE);
if (title != null) new Tag("legend").content(title).addTo(this);
}
}
diff --git a/src/main/java/de/srsoftware/web4rail/tags/Input.java b/src/main/java/de/srsoftware/web4rail/tags/Input.java
index 3bbd63d..ac9bd02 100644
--- a/src/main/java/de/srsoftware/web4rail/tags/Input.java
+++ b/src/main/java/de/srsoftware/web4rail/tags/Input.java
@@ -18,5 +18,10 @@ public class Input extends Tag{
public Tag hideIn(Tag form) {
return this.attr("type", "hidden").addTo(form);
- }
+ }
+
+ public Input numeric() {
+ attr("type","numeric");
+ return this;
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
index cececa8..7546063 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
@@ -78,6 +78,7 @@ public abstract class Tile {
}
public Object click() throws IOException {
+ LOG.debug("Tile.click()");
return propMenu();
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
index 7fc0b81..72d3f2a 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
@@ -1,27 +1,126 @@
package de.srsoftware.web4rail.tiles;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Map;
+import org.json.JSONObject;
+
import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.Device;
+import de.srsoftware.web4rail.Protocol;
+import de.srsoftware.web4rail.tags.Fieldset;
+import de.srsoftware.web4rail.tags.Input;
+import de.srsoftware.web4rail.tags.Label;
+import de.srsoftware.web4rail.tags.Radio;
-public abstract class Turnout extends Tile {
+public abstract class Turnout extends Tile implements Device{
public static final String STATE = "state";
+ private static final String PORT_A = "port_a";
+ private static final String PORT_B = "port_b";
+ protected static final String STRAIGHT = "straight";
+
+ private Protocol protocol = Protocol.DCC128;
+ protected int address = 0;
+ protected int portA = 0, portB = 0;
+ protected int delay = 400;
+ protected boolean initialized;
+
public enum State{
LEFT,STRAIGHT,RIGHT,UNDEF;
}
+
protected State state = State.STRAIGHT;
- public State state() {
- return state;
+ @Override
+ public Object click() throws IOException {
+ LOG.debug("Turnout.click()");
+ Object o = super.click();
+ if (address != 0 && !initialized) {
+ String p = null;
+ switch (protocol) {
+ case DCC14:
+ case DCC27:
+ case DCC28:
+ case DCC128:
+ p = "N";
+ break;
+ case MOTO:
+ p = "M";
+ break;
+ case SELECTRIX:
+ p = "S";
+ break;
+ default:
+ p = "P";
+ }
+ plan.queue("INIT {} GA "+address+" "+p);
+ initialized = true;
+ }
+ return o;
+ }
+
+ protected void init() {
+ if (!initialized) {
+ plan.queue("INIT {} GA "+address+" "+proto());
+ initialized = true;
+ }
+ }
+
+ @Override
+ public JSONObject json() {
+ JSONObject json = super.json();
+ if (portA != 0) json.put(PORT_A, portA);
+ if (portB != 0) json.put(PORT_B, portB);
+ if (address != 0) json.put(ADDRESS, address);
+ json.put(PROTOCOL, protocol);
+ return json;
+ }
+
+ @Override
+ protected Tile load(JSONObject json) throws IOException {
+ if (json.has(ADDRESS)) address = json.getInt(ADDRESS);
+ if (json.has(PORT_A)) portA = json.getInt(PORT_A);
+ if (json.has(PORT_B)) portB = json.getInt(PORT_B);
+ if (json.has(PROTOCOL)) protocol = Protocol.valueOf(json.getString(PROTOCOL));
+ return super.load(json);
}
- public void state(State newState) throws IOException {
- state = newState;
- LOG.debug("Setting {} to {}",this,state);
- plan.stream("place "+tag(null));
+ @Override
+ public Tag propForm() {
+ Tag form = super.propForm();
+ Fieldset fieldset = new Fieldset(t("Decoder settings"));
+ Label protocol = new Label(t("Protocol:"));
+ for (Protocol proto : Protocol.values()) {
+ new Radio(PROTOCOL, proto.toString(), t(proto.toString()), proto == this.protocol).addTo(protocol);
+ }
+ protocol.addTo(fieldset).addTo(form);
+ new Input(ADDRESS, address).numeric().addTo(new Label(t("Address"))).addTo(fieldset);
+ return form;
}
+ private char proto() {
+ switch (protocol) {
+ case DCC14:
+ case DCC27:
+ case DCC28:
+ case DCC128:
+ return 'N';
+ case MOTO:
+ return 'M';
+ case SELECTRIX:
+ return 'S';
+ default:
+ return 'P';
+ }
+ }
+
+ public State state() {
+ return state;
+ }
+
+ public abstract void state(State newState) throws IOException;
+
@Override
public Tag tag(Map replacements) throws IOException {
Tag tag = super.tag(replacements);
@@ -32,4 +131,13 @@ public abstract class Turnout extends Tile {
public void toggle() {
state = State.STRAIGHT;
}
+
+ @Override
+ public Tile update(HashMap params) throws IOException {
+ if (params.containsKey(PROTOCOL)) protocol = Protocol.valueOf(params.get(PROTOCOL));
+ if (params.containsKey(ADDRESS)) address = Integer.parseInt(params.get(ADDRESS));
+ if (params.containsKey(PORT_A)) portA = Integer.parseInt(params.get(PORT_A));
+ if (params.containsKey(PORT_B)) portB = Integer.parseInt(params.get(PORT_B));
+ return super.update(params);
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java b/src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java
index 0dfaa48..e64971d 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java
@@ -1,5 +1,6 @@
package de.srsoftware.web4rail.tiles;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -26,4 +27,10 @@ public class Turnout3E extends Turnout{
return new HashMap<>();
}
}
+
+ @Override
+ public void state(State newState) throws IOException {
+ // TODO Auto-generated method stub
+ LOG.warn("Turnout3E.state({}) not implemented, yet!",newState);
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java
index c59d8c7..c522425 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java
@@ -1,16 +1,65 @@
package de.srsoftware.web4rail.tiles;
import java.io.IOException;
+import java.util.HashMap;
+
+import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.tags.Fieldset;
+import de.srsoftware.web4rail.tags.Input;
+import de.srsoftware.web4rail.tags.Label;
public class TurnoutL extends Turnout {
+
+ private static final String LEFT = "left";
+
@Override
public Object click() throws IOException {
+ LOG.debug("TurnoutL.click()");
+ Object o = super.click();
if (route != null) {
plan.stream(t("{} is locked by {}!",this,route));
- } else {
- state = (state == State.STRAIGHT) ? State.LEFT : State.STRAIGHT;
- plan.stream("place "+tag(null));
+ } else state(state == State.STRAIGHT ? State.LEFT : State.STRAIGHT);
+ return o;
+ }
+
+ @Override
+ public Tag propForm() {
+ Tag form = super.propForm();
+ Tag fieldset = null;
+ for (Tag child : form.children()) {
+ if (child.is(Fieldset.TYPE)) {
+ fieldset = child;
+ break;
+ }
+ }
+ new Input(STRAIGHT, portA).numeric().addTo(new Label(t("Straight port"))).addTo(fieldset);
+ new Input(LEFT, portB).numeric().addTo(new Label(t("Left port"))).addTo(fieldset);
+ return form;
+ }
+
+ @Override
+ public Tile update(HashMap params) throws IOException {
+ if (params.containsKey(STRAIGHT)) portA = Integer.parseInt(params.get(STRAIGHT));
+ if (params.containsKey(LEFT)) portB = Integer.parseInt(params.get(LEFT));
+ return super.update(params);
+ }
+
+ @Override
+ public void state(State newState) throws IOException {
+ init();
+ LOG.debug("Setting {} to {}",this,newState);
+ int p = 0;
+ switch (newState) {
+ case LEFT:
+ p = portB;
+ break;
+ case STRAIGHT:
+ p = portA;
+ break;
+ default:
}
- return propMenu();
+ if (p != 0) plan.queue("SET {} GA "+address+" "+p+" 1 "+delay);
+ state = newState;
+ plan.stream("place "+tag(null));
}
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java
index 46b08dc..bd488b3 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java
@@ -1,16 +1,65 @@
package de.srsoftware.web4rail.tiles;
import java.io.IOException;
+import java.util.HashMap;
+
+import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.tags.Fieldset;
+import de.srsoftware.web4rail.tags.Input;
+import de.srsoftware.web4rail.tags.Label;
public class TurnoutR extends Turnout {
+
+ private static final String RIGHT = "right";
+
@Override
public Object click() throws IOException {
+ LOG.debug("Turnoutr.click()");
+ Object o = super.click();
if (route != null) {
plan.stream(t("{} is locked by {}!",this,route));
- } else {
- state = (state == State.STRAIGHT) ? State.RIGHT : State.STRAIGHT;
- plan.stream("place "+tag(null));
+ } else state(state == State.STRAIGHT ? State.RIGHT : State.STRAIGHT);
+ return o;
+ }
+
+ @Override
+ public Tag propForm() {
+ Tag form = super.propForm();
+ Tag fieldset = null;
+ for (Tag child : form.children()) {
+ if (child.is(Fieldset.TYPE)) {
+ fieldset = child;
+ break;
+ }
+ }
+ new Input(STRAIGHT, portA).addTo(new Label(t("Straight port"))).addTo(fieldset);
+ new Input(RIGHT, portB).addTo(new Label(t("Right port"))).addTo(fieldset);
+ return form;
+ }
+
+ @Override
+ public Tile update(HashMap params) throws IOException {
+ if (params.containsKey(STRAIGHT)) portA = Integer.parseInt(params.get(STRAIGHT));
+ if (params.containsKey(RIGHT)) portB = Integer.parseInt(params.get(RIGHT));
+ return super.update(params);
+ }
+
+ @Override
+ public void state(State newState) throws IOException {
+ init();
+ LOG.debug("Setting {} to {}",this,newState);
+ int p = 0;
+ switch (newState) {
+ case RIGHT:
+ p = portB;
+ break;
+ case STRAIGHT:
+ p = portA;
+ break;
+ default:
}
- return propMenu();
+ if (p != 0) plan.queue("SET {} GA "+address+" "+p+" 1 "+delay);
+ state = newState;
+ plan.stream("place "+tag(null));
}
}