Browse Source

implemented contact feedback

lookup-tables
Stephan Richter 5 years ago
parent
commit
6932536d05
  1. 2
      pom.xml
  2. 14
      resources/js/plan.js
  3. 21
      src/main/java/de/srsoftware/web4rail/Application.java
  4. 1
      src/main/java/de/srsoftware/web4rail/Constants.java
  5. 34
      src/main/java/de/srsoftware/web4rail/Plan.java
  6. 36
      src/main/java/de/srsoftware/web4rail/Route.java
  7. 2
      src/main/java/de/srsoftware/web4rail/tags/Button.java
  8. 113
      src/main/java/de/srsoftware/web4rail/tiles/Contact.java
  9. 7
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

2
pom.xml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId>
<version>0.9.1</version>
<version>0.9.2</version>
<name>Web4Rail</name>
<packaging>jar</packaging>
<description>Java Model Railway Control</description>

14
resources/js/plan.js

@ -120,12 +120,6 @@ function moveTile(x,y){ @@ -120,12 +120,6 @@ function moveTile(x,y){
return request({realm:'plan',action:mode,direction:selected.id,id:id});
}
function openRoute(id){
console.log("openRoute("+id+")");
request({realm:'route',action:PROPS,id:id});
return false;
}
function place(data){
var tag = $(data);
$('#'+tag.attr('id')).remove();
@ -201,6 +195,14 @@ function stream(ev){ @@ -201,6 +195,14 @@ function stream(ev){
if (data.startsWith("remove")) return remove(data.substring(7));
if (data.startsWith("addclass")) return addClass(data.substring(9));
if (data.startsWith("dropclass")) return dropClass(data.substring(10));
if (data.startsWith("<div") && $(data).attr('class') == 'window'){
$('.window').remove();
$(BODY).append($(data));
tileWindow();
return;
}
addMessage(data);
}

21
src/main/java/de/srsoftware/web4rail/Application.java

@ -15,7 +15,6 @@ import java.net.URLDecoder; @@ -15,7 +15,6 @@ import java.net.URLDecoder;
import java.nio.file.Files;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,6 +30,7 @@ import de.srsoftware.web4rail.conditions.Condition; @@ -31,6 +30,7 @@ import de.srsoftware.web4rail.conditions.Condition;
import de.srsoftware.web4rail.moving.Car;
import de.srsoftware.web4rail.moving.Locomotive;
import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tiles.Contact;
/**
* Entry point class for the Web4Rail application
@ -113,6 +113,8 @@ public class Application implements Constants{ @@ -113,6 +113,8 @@ public class Application implements Constants{
return ActionList.process(params,plan);
case REALM_CAR:
return Car.action(params);
case REALM_CONTACT:
return Contact.process(params);
case REALM_CONDITION:
return Condition.action(params,plan);
case REALM_CU:
@ -169,23 +171,6 @@ public class Application implements Constants{ @@ -169,23 +171,6 @@ public class Application implements Constants{
if (response instanceof Page) {
html = ((Page)response).html().toString().getBytes(UTF8);
client.getResponseHeaders().add("content-type", "text/html");
} else if (response instanceof CompletableFuture) {
CompletableFuture<?> promise = (CompletableFuture<?>) response;
promise.thenAccept(object -> {
try {
send(client,object);
} catch (IOException e) {
LOG.warn("Was not able to send {}!",object);
}
}).exceptionally(ex -> {
try {
send(client,ex.getMessage());
} catch (IOException e) {
LOG.warn("Was not able to send {}!",ex);
}
throw new RuntimeException(ex);
});
return;
} else {
html = (response == null ? "" : response.toString()).getBytes(UTF8);
client.getResponseHeaders().add("content-type", "text/plain");

1
src/main/java/de/srsoftware/web4rail/Constants.java

@ -39,6 +39,7 @@ public interface Constants { @@ -39,6 +39,7 @@ public interface Constants {
public static final String REALM_ACTIONS = "actions";
public static final String REALM_CAR = "car";
public static final String REALM_CONDITION = "condition";
public static final String REALM_CONTACT = "contact";
public static final String REALM_CU = "cu";
public static final String REALM_LOCO = "loco";
public static final String REALM_ROUTE = "route";

34
src/main/java/de/srsoftware/web4rail/Plan.java

@ -118,6 +118,7 @@ public class Plan implements Constants{ @@ -118,6 +118,7 @@ public class Plan implements Constants{
private HashSet<Block> blocks = new HashSet<Block>(); // the list of tiles, that are blocks
private HashMap<Integer, Route> routes = new HashMap<Integer, Route>(); // the list of routes of the track layout
private ControlUnit controlUnit = new ControlUnit(this); // the control unit, to which the plan is connected
private Contact learningContact;
/**
* creates a new plan, starts to send heart beats
@ -588,14 +589,15 @@ public class Plan implements Constants{ @@ -588,14 +589,15 @@ public class Plan implements Constants{
/**
* removes a route from the track layout
* @param route
* @return
*/
public void remove(Route route) {
public String remove(Route route) {
for (Tile tile : route.path()) tile.remove(route);
for (Train train : Train.list()) {
if (train.route == route) train.route = null;
}
routes.remove(route.id());
stream(t("Removed {}.",route));
return t("Removed {}.",route);
}
/**
@ -660,7 +662,19 @@ public class Plan implements Constants{ @@ -660,7 +662,19 @@ public class Plan implements Constants{
}
public void sensor(int addr, boolean active) {
LOG.debug("contact({},{})",addr,active);
Contact contact = Contact.get(addr);
LOG.debug("contact: {}",contact);
LOG.debug("learning: {}",learningContact);
if (contact != null) {
contact.activate(active);
} else {
if (active && learningContact != null) {
LOG.debug("learned: {} = {}",addr,learningContact);
stream(learningContact.addr(addr).propMenu().toString());
learningContact = null;
}
}
}
@ -669,13 +683,17 @@ public class Plan implements Constants{ @@ -669,13 +683,17 @@ public class Plan implements Constants{
* @param params
* @return
*/
public Window showContext(HashMap<String, String> params) {
public Tag showContext(HashMap<String, String> params) {
String[] parts = params.get(CONTEXT).split(":");
String realm = parts[0];
String id = parts.length>1 ? parts[1] : null;
switch (realm) {
case REALM_ROUTE:
return route(Integer.parseInt(id)).properties();
return route(Integer.parseInt(id)).properties(params);
case REALM_PLAN:
Tile tile = get(id, false);
return tile == null? null : tile.propMenu();
}
return null;
}
@ -795,4 +813,10 @@ public class Plan implements Constants{ @@ -795,4 +813,10 @@ public class Plan implements Constants{
public void warn(Contact contact) {
stream(t("Warning: {}",t("Ghost train @ {}",contact)));
}
public void learn(Contact contact) {
learningContact = contact;
LOG.debug("learning contact {}",learningContact);
}
}

36
src/main/java/de/srsoftware/web4rail/Route.java

@ -87,10 +87,21 @@ public class Route implements Constants{ @@ -87,10 +87,21 @@ public class Route implements Constants{
Route route = plan.route(Integer.parseInt(params.get(ID)));
if (route == null) return t("Unknown route: {}",params.get(ID));
switch (params.get(ACTION)) {
case ACTION_UPDATE:
return route.update(params);
case ACTION_DROP:
String message = plan.remove(route);
String tileId = params.get(Tile.class.getSimpleName());
if (tileId != null) {
Tile tile = plan.get(tileId, false);
if (tile != null) {
plan.stream(message);
return tile.propMenu();
}
}
return message;
case ACTION_PROPS:
return route.properties();
return route.properties(params);
case ACTION_UPDATE:
return route.update(params,plan);
}
return t("Unknown action: {}",params.get(ACTION));
}
@ -199,12 +210,12 @@ public class Route implements Constants{ @@ -199,12 +210,12 @@ public class Route implements Constants{
}
}
private void addFormTo(Window win) {
private void addFormTo(Window win, HashMap<String, String> params) {
Form form = new Form("route-"+id+"-props");
new Input(ACTION, ACTION_UPDATE).hideIn(form);
new Input(REALM,REALM_ROUTE).hideIn(form);
new Input(ID,id()).hideIn(form);
if (params.containsKey(CONTEXT)) new Input(CONTEXT,params.get(CONTEXT)).hideIn(form);
Tag label = new Tag("label").content(t("name:")+NBSP);
new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).style("width: 80%").addTo(label);
label.addTo(form);
@ -475,9 +486,9 @@ public class Route implements Constants{ @@ -475,9 +486,9 @@ public class Route implements Constants{
return result;
}
public Window properties() {
public Window properties(HashMap<String, String> params) {
Window win = new Window("route-properties",t("Properties of {}",this));
addFormTo(win);
addFormTo(win,params);
addBasicPropertiesTo(win);
addTurnoutsTo(win);
addConditionsTo(win);
@ -565,7 +576,7 @@ public class Route implements Constants{ @@ -565,7 +576,7 @@ public class Route implements Constants{
return this;
}
public Object update(HashMap<String, String> params) {
public Object update(HashMap<String, String> params,Plan plan) {
LOG.debug("update({})",params);
String name = params.get(NAME);
if (name != null) name(name);
@ -573,8 +584,13 @@ public class Route implements Constants{ @@ -573,8 +584,13 @@ public class Route implements Constants{
String condition = params.get(REALM_CONDITION);
if (condition != null) {
addCondition(condition);
return properties();
return properties(params);
}
String message = t("{} updated.",this);
if (params.containsKey(CONTEXT)) {
plan.stream(message);
return plan.showContext(params);
}
return t("{} updated.",this);
return message;
}
}

2
src/main/java/de/srsoftware/web4rail/tags/Button.java

@ -26,7 +26,7 @@ public class Button extends Tag { @@ -26,7 +26,7 @@ public class Button extends Tag {
this(text,"return submitForm('"+form.get("id")+"');");
}
public Button(String text, Map<String, Object> props) {
public Button(String text, Map<String, ? extends Object> props) {
this(text,"request("+(new JSONObject(props).toString().replace("\"", "'"))+")");
}
}

113
src/main/java/de/srsoftware/web4rail/tiles/Contact.java

@ -1,40 +1,120 @@ @@ -1,40 +1,120 @@
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.tags.Button;
import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
public abstract class Contact extends Tile{
private static final String ADDRESS = "address";
private static final HashMap<String, Contact> contactsById = new HashMap<String, Contact>();
private static final HashMap<Integer, Contact> contactsByAddr = new HashMap<Integer, Contact>();
private boolean active = false;
private String trigger = null;
public void activate() throws IOException {
active = true;
stream();
private int addr = 0;
public void trigger(int duration) throws IOException {
activate(true);
new Thread() {
public void run() {
try {
sleep(200);
active=false;
stream();
sleep(duration);
activate(false);
} catch (Exception e) {}
}
}.start();
if (route == null) {
plan.warn(this);
} else {
route.contact(this);
}
public void activate(boolean active) {
this.active = active;
if (active) {
if (route == null) {
plan.warn(this);
} else {
route.contact(this);
}
}
try {
stream();
} catch (IOException e) {
e.printStackTrace();
}
}
public Contact addr(int address) {
addr = address;
contactsByAddr.put(addr, this);
return this;
}
@Override
public Object click() throws IOException {
activate();
trigger(200);
return super.click();
}
public static Contact get(int addr) {
return contactsByAddr.get(addr);
}
@Override
public JSONObject json() {
JSONObject json = super.json();
if (addr > 0) json.put(ADDRESS, addr);
return json;
}
@Override
protected Tile load(JSONObject json) throws IOException {
super.load(json);
if (json.has(ADDRESS)) addr(json.getInt(ADDRESS));
return this;
}
@Override
public Tile position(int x, int y) {
super.position(x, y);
contactsById.put(id(), this);
return this;
}
public static Object process(HashMap<String, String> params) {
String action = params.get(ACTION);
String id = params.get(ID);
if (action == null) return t("Missing ACTION on call to {}.process()",Contact.class.getSimpleName());
Contact contact;
switch (action) {
case ACTION_ANALYZE:
if (id == null) return t("Missing ID on call to {}.process()",Contact.class.getSimpleName());
contact = contactsById.get(id);
if (contact == null) return t("No contact with id {} found!",id);
Tag propMenu = contact.propMenu();
propMenu.children().insertElementAt(new Tag("div").content(t("Trigger a feedback sensor to assign it with this contact!")), 1);
contact.plan.learn(contact);
return propMenu;
}
return t("Unknown action: {}",action);
}
@Override
public Tag propForm(String formId) {
Tag form = super.propForm(formId);
new Tag("h4").content(t("Hardware settings")).addTo(form);
Tag label = new Input(ADDRESS, addr).addTo(new Label(t("Address:")+NBSP));
Map<String, String> props = Map.of(REALM,REALM_CONTACT,ID,id(),ACTION,ACTION_ANALYZE);
new Button(t("learn"), props).addTo(label).addTo(form);
return form;
}
public void stream() throws IOException {
Tag tag = super.tag(null);
if (active) tag.clazz(tag.get("class")+" active");
@ -46,5 +126,12 @@ public abstract class Contact extends Tile{ @@ -46,5 +126,12 @@ public abstract class Contact extends Tile{
if (trigger == null) trigger = getClass().getSimpleName()+"-"+id();
return trigger;
}
@Override
public Tile update(HashMap<String, String> params) throws IOException {
if (params.containsKey(ADDRESS)) addr(Integer.parseInt(params.get(ADDRESS)));
return super.update(params);
}
}

7
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -180,8 +180,8 @@ public abstract class Tile implements Constants{ @@ -180,8 +180,8 @@ public abstract class Tile implements Constants{
return new Vector<Plan.Direction>();
}
public Tag propForm(String id) {
Form form = new Form(id);
public Tag propForm(String formId) {
Form form = new Form(formId);
new Input(ACTION, ACTION_UPDATE).hideIn(form);
new Input(REALM, REALM_PLAN).hideIn(form);
new Input(ID,id()).hideIn(form);
@ -216,7 +216,8 @@ public abstract class Tile implements Constants{ @@ -216,7 +216,8 @@ public abstract class Tile implements Constants{
new Tag("h4").content(t("Routes using this tile:")).addTo(window);
Tag routeList = new Tag("ol");
for (Route route : routes) {
Tag li = new Tag("span").attr("onclick","openRoute('"+route.id()+"')").content(route.name()+NBSP).addTo(new Tag("li").clazz("link"));
String json = new JSONObject(Map.of(REALM,ROUTE,ID,route.id(),ACTION,ACTION_PROPS,CONTEXT,REALM_PLAN+":"+id())).toString().replace("\"", "'");
Tag li = new Tag("span").attr("onclick","return request("+json+");").content(route.name()+NBSP).addTo(new Tag("li").clazz("link"));
Map<String, Object> params = Map.of(REALM,REALM_ROUTE,ID,route.id(),ACTION,ACTION_DROP,Tile.class.getSimpleName(),id());
new Button(t("delete route"),params).addTo(li);
li.addTo(routeList);

Loading…
Cancel
Save