diff --git a/Bugs.txt b/Bugs.txt
index a549001..b5f09e5 100644
--- a/Bugs.txt
+++ b/Bugs.txt
@@ -1,7 +1,4 @@
2020-02-09:
-- Züge fahren falsch herrum
-- Speed und Fahrtrichtung werden nicht in den Zügen geupdated
-- Max Speed ist nicht gleich der Maximalste Step
-
+- Reverse funktioniert nicht immer.
diff --git a/ChangeLog b/ChangeLog
index 6d02a1c..0b49d79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-06:
+- fixed: speed and stepcoding
+
+2020-03-03:
+- adding new loco ctrl interface.
+
2020-02-09:
- Initial CVS Import
diff --git a/server/interface-z21.cc b/server/interface-z21.cc
index c32c0b8..8145a7b 100644
--- a/server/interface-z21.cc
+++ b/server/interface-z21.cc
@@ -359,12 +359,12 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
//
// setup steps and selected step
- if (l->steps <= 14) {
+ if (l->stepcode == LOCO_INT_DCC14) {
buffer[Z21_IDX_SETLOCO_DRIVE_SFMT] = 0x10;
if (step == 0) buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= 0;
else buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= (abs(step)+1);
}
- else if (l->steps <= 28) {
+ else if (l->stepcode == LOCO_INT_DCC28) {
buffer[Z21_IDX_SETLOCO_DRIVE_SFMT] = 0x12;
if (step == 0) buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= 0;
else {
@@ -372,7 +372,7 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
if (abs(step) & 0x01) buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= 0x10;
}
}
- else if (l->steps <= 128) {
+ else if (l->stepcode == LOCO_INT_DCC128) {
buffer[Z21_IDX_SETLOCO_DRIVE_SFMT] = 0x13;
if (step == 0) buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= 0;
else buffer[Z21_IDX_SETLOCO_DRIVE_STEP] |= (abs(step)+1);
@@ -394,7 +394,7 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
loconet_last.dir = l->flags & LOCO_F_REVERSE;
loconet_last.speed = l->speed;
loconet_last.maxspeed = l->vmax;
- loconet_last.steps = l->steps;
+ loconet_last.stepcode = l->stepcode;
};
diff --git a/server/interface-z21.h b/server/interface-z21.h
index 5bb5833..589afea 100644
--- a/server/interface-z21.h
+++ b/server/interface-z21.h
@@ -23,7 +23,7 @@
struct s_loconet_map{
int addr;
int dir;
- int steps;
+ int stepcode;
int speed;
int maxspeed;
};
diff --git a/server/interface.cc b/server/interface.cc
index b2cdf7b..0be242e 100644
--- a/server/interface.cc
+++ b/server/interface.cc
@@ -339,14 +339,18 @@ void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) {
void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
int i;
- int step = 0;
+ int step = 0, maxstep = 0;
- // TEST
- // (l->steps-1) ?????
+ switch(l->stepcode) {
+ case LOCO_INT_DCC14: maxstep = 14; break;
+ case LOCO_INT_DCC28: maxstep = 28; break;
+ case LOCO_INT_DCC128: maxstep = 126; break;
+ default: maxstep = 0; break;
+ }
if (abs(speed) < l->vmin) step = 0;
- if (abs(speed) >= l->vmin) step = (speed * (l->steps)) / l->vmax;
- if (abs(speed) > l->vmax) step = l->steps;
+ if (abs(speed) >= l->vmin) step = (speed * (maxstep)) / l->vmax;
+ if (abs(speed) > l->vmax) step = maxstep;
l->speed = speed;
diff --git a/server/locomotive.cc b/server/locomotive.cc
index 4d7a11d..9395b70 100644
--- a/server/locomotive.cc
+++ b/server/locomotive.cc
@@ -40,7 +40,7 @@ JSONParse Locomotives::_GetJSON(int idx) {
s = locomotives[idx].name; json.AddObject("name", s);
s = locomotives[idx].ifname; json.AddObject("ifname", s);
json.AddObject("addr", locomotives[idx].addr);
- json.AddObject("steps", locomotives[idx].steps);
+ json.AddObject("stepcode", locomotives[idx].stepcode);
json.AddObject("speed", locomotives[idx].speed);
json.AddObject("func", locomotives[idx].func);
json.AddObject("flags", locomotives[idx].flags);
@@ -103,7 +103,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
l.name[0] = 0;
l.ifname[0] = 0;
l.addr = 0;
- l.steps = 0;
+ l.stepcode = 0;
l.vmin = 0;
l.vslow = 0;
l.vmid = 0;
@@ -118,7 +118,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
j->GetValue("ifname", &s);
strncpy (l.ifname, s.c_str(), REFERENCENAME_LEN);
j->GetValueInt("addr", &l.addr);
- j->GetValueInt("steps", &l.steps);
+ j->GetValueInt("stepcode", &l.stepcode);
j->GetValueInt("speed", &l.speed);
j->GetValueInt64("func", &l.func);
j->GetValueInt("flags", &l.flags);
@@ -171,7 +171,7 @@ int Locomotives::Delete(string name) {
locomotives[i].name[0] = 0;
locomotives[i].ifname[0] = 0;
locomotives[i].addr = 0;
- locomotives[i].steps = 0;
+ locomotives[i].stepcode = 0;
locomotives[i].vmin = 0;
locomotives[i].vslow = 0;
locomotives[i].vmid = 0;
@@ -253,15 +253,23 @@ int Locomotives::SetSpeedFromBus(string ifname, int addr, int speed) {
int i;
JSONParse jp;
+
debug (0, "%s:%d SetSpeedFromBus IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
+ int maxstep;
+ switch(locomotives[i].stepcode) {
+ case LOCO_INT_DCC14: maxstep = 14; break;
+ case LOCO_INT_DCC28: maxstep = 28; break;
+ case LOCO_INT_DCC128: maxstep = 126; break;
+ default: maxstep = 0; break;
+ }
+
if (speed == 0) locomotives[i].speed = 0;
- if (speed >= (127-((127/locomotives[i].steps)+1))) locomotives[i].speed = locomotives[i].vmax;
+ if (speed >= (127-((127/maxstep)+1))) locomotives[i].speed = locomotives[i].vmax;
else {
- printf ("\n\n Speed:%d test:%d", speed, (127-((127/locomotives[i].steps)+1)));
- locomotives[i].speed = (1+speed) * locomotives[i].vmax / 127;
+ locomotives[i].speed = speed * locomotives[i].vmax / 127;
if (locomotives[i].speed > locomotives[i].vmax) locomotives[i].speed = locomotives[i].vmax;
}
diff --git a/server/locomotive.h b/server/locomotive.h
index c8c926e..949f4ea 100644
--- a/server/locomotive.h
+++ b/server/locomotive.h
@@ -6,11 +6,17 @@
#include "server.h"
#define LOCO_F_REVERSE 0x0001
+enum {
+ LOCO_INT_UNDEF = 0,
+ LOCO_INT_DCC14,
+ LOCO_INT_DCC28,
+ LOCO_INT_DCC128
+};
struct s_Locomotive {
char name[REFERENCENAME_LEN];
char ifname[REFERENCENAME_LEN];
- int steps;
+ int stepcode;
int speed;
int64_t func;
int flags;
diff --git a/webinterface/gui/gui.js b/webinterface/gui/gui.js
index d70b0b4..1ca603e 100644
--- a/webinterface/gui/gui.js
+++ b/webinterface/gui/gui.js
@@ -19,3 +19,16 @@ function gAddEventListener (id, eventname, callback) {
if (obj) obj.addEventListener(eventname, callback);
};
+
+//
+// get the text between Text1 and Text2
+function getTextBetween(fulltext, text1, text2) {
+ var end1 = text1.length;
+ var start2 = fulltext.length-text2.length;
+
+ if (end1 < start2) {
+ return fulltext.substr(text1.length, start2-end1);
+ }
+ else return "";
+};
+
diff --git a/webinterface/index.html b/webinterface/index.html
index a8aeb49..5dd92f7 100644
--- a/webinterface/index.html
+++ b/webinterface/index.html
@@ -51,7 +51,7 @@
-
+
+
+
+
+
+
+
+
diff --git a/webinterface/layout.css b/webinterface/layout.css
index 4122db4..bf1ec32 100644
--- a/webinterface/layout.css
+++ b/webinterface/layout.css
@@ -6,7 +6,7 @@ body {
:root {
--top-height: 34px;
--side-width: 37px;
- --bottom-height: 32px;
+ --bottom-height: 132px;
--menu-bg-color: #333;
--menu-fg-color: linen;
}
diff --git a/webinterface/locomotive.js b/webinterface/locomotive.js
index 9cfc0e7..d254ab1 100644
--- a/webinterface/locomotive.js
+++ b/webinterface/locomotive.js
@@ -16,7 +16,7 @@ function locomotive_Update(data) {
locomotives[i].name = data.name;
locomotives[i].ifname = data.ifname;
locomotives[i].addr = data.addr;
- locomotives[i].steps = data.steps;
+ locomotives[i].stepcode = data.stepcode;
locomotives[i].speed = data.speed;
locomotives[i].vmin = data.vmin;
locomotives[i].vslow = data.vslow;
@@ -24,6 +24,9 @@ function locomotive_Update(data) {
locomotives[i].vfast = data.vfast;
locomotives[i].vmax = data.vmax;
locomotives[i].flags = data.flags;
+
+ locodetail_setData(locomotives[i]);
+ lococtrl_setData(data);
return;
}
}
@@ -123,7 +126,11 @@ function locodetail_show(loconame) {
Vmax: | | |
\
\
\
- Steps: \
+ \
Speed: \
\
|
\
@@ -143,6 +150,10 @@ function locodetail_show(loconame) {
gAddEventListener("locodet_btnvmax", 'click', locodetail_cb_btnmove);
gAddEventListener("locodet_reverse", 'click', locodetail_cb_reverse);
+// gAddEventListener("locodet_DCC14", 'click', locodetail_cb_stepcode);
+// gAddEventListener("locodet_DCC28", 'click', locodetail_cb_stepcode);
+// gAddEventListener("locodet_DCC128", 'click', locodetail_cb_stepcode);
+
gAddEventListener("locodet_CLOSE", 'click', locodetail_cb_close);
gAddEventListener("locodet_DELETE", 'click', locodetail_cb_delete);
gAddEventListener("locodet_SAVE", 'click', locodetail_cb_save);
@@ -165,7 +176,6 @@ function locodetail_show(loconame) {
};
-
//
// reverse selected, setup flags
function locodetail_cb_reverse () {
@@ -182,8 +192,6 @@ function locodetail_cb_reverse () {
};
-
-
function locodetail_cb_btnmove () {
var win = document.getElementById("locodetail");
var loco_name = document.getElementById("locodet_name");
@@ -217,6 +225,7 @@ function locodetail_cb_close () {
if (win) document.body.removeChild(win);
};
+
//
// Callback: Delete Button
//
@@ -296,7 +305,6 @@ function locodetail_setData(elm) {
var loco_addr = document.getElementById("locodet_addr");
var loco_speed = document.getElementById("locodet_speed");
var loco_flags = document.getElementById("locodet_flags");
- var loco_steps = document.getElementById("locodet_steps");
var loco_vmin = document.getElementById("locodet_vmin");
var loco_vslow = document.getElementById("locodet_vslow");
var loco_vmid = document.getElementById("locodet_vmid");
@@ -310,7 +318,6 @@ function locodetail_setData(elm) {
if (loco_flags) loco_flags.value = elm.flags;
if (loco_addr) loco_addr.value = elm.addr;
if (loco_speed) loco_speed.value = elm.speed;
- if (loco_steps) loco_steps.value = elm.steps;
if (loco_vmin) loco_vmin.value = elm.vmin;
if (loco_vslow) loco_vslow.value = elm.vslow;
if (loco_vmid) loco_vmid.value = elm.vmid;
@@ -322,6 +329,13 @@ function locodetail_setData(elm) {
}
}
+
+ var codes = document.getElementsByName('STEPCODE');
+ for(var i = 0; i < codes.length; i++) {
+// debug ("STEPCODE: elm.stepcode: " + elm.stepcode + " i:" + i + " codes[i].value: " + codes[i].value + " codes.id: " + codes[i].id);
+ if(elm.stepcode == codes[i].value) codes[i].checked = true;
+ else codes[i].checked = false;
+ }
};
@@ -330,31 +344,191 @@ function locodetail_setData(elm) {
// return all elements from the dialogbox
//
function locodetail_getData() {
- var res = { name: "", ifname: "", addr: "", flags: 0, steps: "",
+ var res = { name: "", ifname: "", addr: "", flags: 0, stepcode:"0",
vmin: "20", vslow: "40", vmid:"60", vfast:"80", vmax:"100" };
+ var codes = document.getElementsByName('STEPCODE');
+ for(var i = 0; i < codes.length; i++){
+ if(codes[i].checked){
+ res.stepcode = codes[i].value;
+ }
+ }
+
var loco_name = document.getElementById("locodet_name");
var loco_ifname = document.getElementById("locodet_ifname");
var loco_flags = document.getElementById("locodet_flags");
var loco_addr = document.getElementById("locodet_addr");
- var loco_steps = document.getElementById("locodet_steps");
var loco_vmin = document.getElementById("locodet_vmin");
var loco_vslow = document.getElementById("locodet_vslow");
var loco_vmid = document.getElementById("locodet_vmid");
var loco_vfast = document.getElementById("locodet_vfast");
var loco_vmax = document.getElementById("locodet_vmax");
+ var loco_speed = document.getElementById("locodet_speed");
if (loco_name) res.name = loco_name.value;
if (loco_ifname) res.ifname = loco_ifname.value;
if (loco_flags) res.flags = loco_flags.value;
if (loco_addr) res.addr = loco_addr.value;
- if (loco_steps) res.steps = loco_steps.value;
if (loco_vmin) res.vmin = loco_vmin.value;
if (loco_vslow) res.vslow = loco_vslow.value;
if (loco_vmid) res.vmid = loco_vmid.value;
if (loco_vfast) res.vfast = loco_vfast.value;
if (loco_vmax) res.vmax = loco_vmax.value;
+ if (loco_speed) res.speed = loco_speed.speed;
return res;
};
+
+// ***********************************************************************************************
+// ***********************************************************************************************
+// locolist: show a list of locomotives.
+//
+// ***********************************************************************************************
+// ***********************************************************************************************
+function locolist_show() {
+ var win = document.getElementById("locolist");
+
+ debug ("locolist_show");
+
+ if (!win) {
+ debug ("locolist_show create window");
+ win = gWindowCreate("locolist", "Locomotives", 400, 500, " \
+ \
+ \
+ \
+
\
+ \
+ ");
+
+ gAddEventListener("locolist_CLOSE", 'click', locolist_cb_close);
+ }
+
+ var ul = document.getElementById("locolist_elements");
+
+ //
+ // clear list
+
+
+ //
+ // append all locomotives
+ for (var i = 0; i < locomotives.length; i++) {
+ let li = document.createElement("li");
+ li.appendChild(document.createTextNode(locomotives[i].name));
+ li.setAttribute("id", "locol_elm_"+locomotives[i].name);
+ ul.appendChild(li);
+
+ gAddEventListener("locol_elm_"+locomotives[i].name, 'click', locolist_clicked);
+ }
+
+};
+
+
+function locolist_clicked() {
+ var i;
+
+ debug ("childnodes: " + this.childNodes[0].textContent);
+ lococtrl_show(this.childNodes[0].textContent);
+};
+
+
+
+function locolist_cb_close () {
+ var win = document.getElementById("locolist");
+
+ if (win) document.body.removeChild(win);
+};
+
+
+
+
+// ***********************************************************************************************
+// ***********************************************************************************************
+// locoshow: show controls for a loco loco_NAME
+//
+// ***********************************************************************************************
+// ***********************************************************************************************
+function lococtrl_show(name) {
+ var win = document.getElementById("lococtrl_"+name);
+ var i;
+
+ debug ("lococtrl_show:" + name);
+
+ if (!win) {
+ debug ("locolist_show create window");
+ win = gWindowCreate("lococtrl_"+name, "Loco:"+name, 200, 500, " \
+ \
+ \
+ \
+
\
+ \
+ ");
+
+ gAddEventListener("lococtrl_"+name+"_RANGE", 'click', lococtrl_speed);
+ gAddEventListener("lococtrl_"+name+"_REVBTN", 'click', lococtrl_reverse);
+ gAddEventListener("lococtrl_"+name+"_CLOSE", 'click', lococtrl_close);
+ }
+ for (var i = 0; i < locomotives.length; i++) {
+ if (name == locomotives[i].name) lococtrl_setData(locomotives[i]);
+ }
+
+};
+
+
+function lococtrl_reverse() {
+ var name = getTextBetween(this.id, "lococtrl_", "_REVBTN");
+ var reverse;
+
+ for (var i = 0; i < locomotives.length; i++) {
+ if (name == locomotives[i].name) {
+ if (locomotives[i].flags & 1) reverse = 0;
+ else reverse = 1;
+ locomotive_server_Set ({name: name, reverse: reverse});
+ }
+ }
+};
+
+
+function lococtrl_speed() {
+ var name = getTextBetween(this.id, "lococtrl_", "_RANGE");
+
+ debug ("Speed Loco:'"+name+"' Speed:'"+this.value+"'");
+ for (var i = 0; i < locomotives.length; i++) {
+ if (name == locomotives[i].name) {
+ locomotive_server_Set ({name: name, speed: this.value});
+ }
+ }
+};
+
+
+function lococtrl_setData(data) {
+ var range = document.getElementById("lococtrl_"+data.name+"_RANGE");
+
+
+ if (range) {
+ debug ("lococtrl: speed:" + data.speed);
+ range.min = 0;
+ range.max = data.vmax;
+ range.value = Math.abs(data.speed);
+ }
+};
+
+
+function lococtrl_close() {
+ debug ("LocoCtrl_close:" + this.value);
+
+ var win = document.getElementById("lococtrl_"+this.value);
+ if (win) document.body.removeChild(win);
+};
+
+
diff --git a/webinterface/side.js b/webinterface/side.js
index ac30fa7..d2f3dcc 100644
--- a/webinterface/side.js
+++ b/webinterface/side.js
@@ -7,17 +7,20 @@ const SIDE_DISPLAY_NONE = 1;
const SIDE_DISPLAY_EDITTRACK = 2;
function side_Display(type) {
- var x = document.getElementById("side_trackedit");
+ var side_track = document.getElementById("side_trackeditbuttons");
+ var side_normal = document.getElementById("side_normalbuttons");
var btn = document.getElementById("mode-none");
debug ("side_display(" + type +")");
if (type == SIDE_DISPLAY_EDITTRACK) {
- x.style.display = "block";
+ side_normal.style.display = "none";
+ side_track.style.display = "block";
}
else {
sideBtnModeClick(btn);
- x.style.display = "none";
+ side_track.style.display = "none";
+ side_normal.style.display = "block";
}
}
@@ -78,6 +81,23 @@ function sideBtnModeClick (obj) {
};
+//
+// show a list of locomotives
+//
+function sideBtnLocoClick () {
+ locolist_show();
+};
+
+
+//
+// send sensor and turnout reset to server.
+//
+function sideBtnResetClick () {
+ var request = { command: "resetdata" };
+ serverinout (request, serverinout_defaultCallback);
+};
+
+
function sideBtnModeGet () {
var i, selected = "";