diff --git a/ChangeLog b/ChangeLog
index 100b367..280b6a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-10:
+- adding support for scheduling ways
+- fixed: webinterface, update on loco will now change its detail display
+
2021-12-02:
- mark blocks as onlyCARGO or onlyPESSANGER, random-automode looks nice now.
- webinterface: debug messages will be print to the console.
diff --git a/server/locomotive.cc b/server/locomotive.cc
index 9c7a0f6..b9fcb57 100644
--- a/server/locomotive.cc
+++ b/server/locomotive.cc
@@ -45,6 +45,7 @@ JSONParse Locomotives::_GetJSON(int idx) {
s = locomotives[idx].blockprev; json.AddObject("blockprev", s);
s = locomotives[idx].auto_way; json.AddObject("auto_way", s);
s = locomotives[idx].auto_wayold; json.AddObject("auto_wayold", s);
+ s = locomotives[idx].schedway; json.AddObject("schedway", s);
json.AddObject("addr", locomotives[idx].addr);
json.AddObject("stepcode", locomotives[idx].stepcode);
json.AddObject("speed", locomotives[idx].speed);
@@ -118,6 +119,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
l.flags = 0;
l.speed = 0;
l.func = 0;
+ l.schedway[0] = 0;
l.blockassign[0] = 0;
l.blockdest[0] = 0;
l.blocknext[0] = 0;
@@ -140,6 +142,9 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
strncpy (l.blockprev, s.c_str(), REFERENCENAME_LEN);
j->GetValue("blocknext", &s);
strncpy (l.blocknext, s.c_str(), REFERENCENAME_LEN);
+ j->GetValue("schedway", &s);
+ strncpy (l.schedway, s.c_str(), WAYDATA_LEN);
+
j->GetValueInt("addr", &l.addr);
j->GetValueInt("stepcode", &l.stepcode);
j->GetValueInt("speed", &l.speed);
@@ -155,6 +160,11 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
};
+/*
+ * this function gets called if some configuration data has changed.
+ * We will ignore the functions and speed settings. This has to be set with the SetFunction
+ * and SetSpeed calls.
+ */
int Locomotives::Change(Locomotive *loco) {
int i;
int ifree = -1;
@@ -174,8 +184,7 @@ int Locomotives::Change(Locomotive *loco) {
locomotives[i].vfast = loco->vfast;
locomotives[i].vmax = loco->vmax;
locomotives[i].flags = loco->flags;
-// locomotives[i].speed = 0;
-// locomotives[i].func = 0;
+ strncpy (locomotives[i].schedway, loco->schedway, WAYDATA_LEN);
ifree = i;
break;
@@ -189,6 +198,7 @@ int Locomotives::Change(Locomotive *loco) {
locomotives[ifree] = *loco;
strncpy (locomotives[ifree].name, loco->name, REFERENCENAME_LEN);
strncpy (locomotives[ifree].ifname, loco->ifname, REFERENCENAME_LEN);
+ strncpy (locomotives[ifree].schedway, loco->schedway, WAYDATA_LEN);
}
changed = 1;
@@ -206,6 +216,7 @@ int Locomotives::Delete(string name) {
if (name.compare(locomotives[i].name) == 0) {
locomotives[i].name[0] = 0;
locomotives[i].ifname[0] = 0;
+ locomotives[i].schedway[0] = 0;
locomotives[i].addr = 0;
locomotives[i].stepcode = 0;
locomotives[i].vmin = 0;
@@ -384,7 +395,10 @@ int Locomotives::Reset(string name) {
locomotives[i].blocknext[0] = 0;
locomotives[i].auto_way[0] = 0;
locomotives[i].auto_wayold[0] = 0;
- locomotives[i].auto_onroute = -1;
+ locomotives[i].auto_onroute = 0;
+ locomotives[i].auto_data = 0;
+ locomotives[i].auto_timenext = { 0 };
+ locomotives[i].sched_step = 0;
break;
}
@@ -408,6 +422,7 @@ int Locomotives::SetMan(string name) {
locomotives[i].auto_onroute = 0;
locomotives[i].auto_way[0] = 0;
locomotives[i].auto_wayold[0] = 0;
+ locomotives[i].sched_step = 0;
break;
}
UnLock();
@@ -534,6 +549,87 @@ string Locomotives::GetName(int idx) {
};
+/*
+ * Locomotive is on auto, do the scheduled steps
+ */
+int Locomotives::SchedulerNextStep(Locomotive *loc) {
+ int stepsmax = 0; // number of found steps
+ int stepcurpos = 0; // current pos in way string
+ int stepnextpos = -1; // next pos;
+ int schedwaylen = 0;
+ int i;
+ string name;
+ string next;
+
+ if (loc == NULL) return 0;
+
+ debug (0, "Locomotives::SchedulerNextStep loc:%s Step:%d", loc->name, loc->sched_step);
+ name = loc->name;
+
+ //
+ // find number of scheduled steps, current pos and next pos
+ for (i = 0; i < WAYDATA_LEN && loc->schedway[i] != 0; i++)
+ if (loc->schedway[i] == ',') {
+ stepsmax++;
+ if (stepsmax == loc->sched_step) stepcurpos = i;
+ else if (loc->sched_step == 0 || (stepcurpos > 0 && stepnextpos == -1)) stepnextpos = i+1;
+ }
+ schedwaylen = i;
+ if (stepnextpos == -1) stepnextpos = 0; // no next step found point to first
+
+ //
+ // set next way
+ if (stepnextpos == 0) loc->sched_step = 0;
+ else loc->sched_step++;
+ if (loc->sched_step > stepsmax) {
+ loc->sched_step = 0;
+ stepnextpos = 0;
+ }
+
+ // read parameter of step
+ for (next = "", i = stepnextpos; i < WAYDATA_LEN && loc->schedway[i] != ',' && loc->schedway[i] != 0; i++) {
+ if (i > stepnextpos+1) next += loc->schedway[i];
+ }
+ debug (0, "Locomotives::SchedulerNextStep loc:%s Next Pos: '%s'", loc->name, loc->schedway+stepnextpos);
+
+ if (loc->schedway[stepnextpos] && stepnextpos < schedwaylen-2) {
+
+ switch (loc->schedway[stepnextpos]) {
+ case ('W'):
+ case ('w'):
+ gettimeofday (&loc->auto_timenext, NULL);
+ loc->auto_timenext.tv_sec += atoi (next.c_str());
+ loc->auto_data = 0;
+ loc->auto_onroute = LOCO_OR_STOPWAIT;
+ break;
+ case ('B'):
+ case ('b'):
+ gettimeofday (&loc->auto_timenext, NULL);
+ snprintf (loc->blockdest, REFERENCENAME_LEN, "%s", next.c_str());
+ loc->auto_timenext.tv_sec += atoi (next.c_str());
+ loc->auto_data = 0;
+ loc->auto_onroute = LOCO_OR_SEARCH;
+ break;
+ case ('R'):
+ case ('r'):
+ if (loc->blockassign[0] == '-') loc->blockassign[0] = '+';
+ else if (loc->blockassign[0] == '+') loc->blockassign[0] = '-';
+
+ if (loc->flags & LOCO_F_REVERSE) loc->flags &= ~LOCO_F_REVERSE;
+ else loc->flags |= LOCO_F_REVERSE;
+
+ break;
+ default:
+ debug (0, "Locomotives::SchedulerNextStep Unknown Command: '%c' loc:%s way:'%s'", loc->name,
+ loc->schedway[stepnextpos], loc->schedway);
+ break;
+ }
+ }
+
+ SendUpdate(loc);
+
+ return 0;
+}
//
// with each call only check one single step of the way, if we have to
@@ -589,6 +685,24 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
}
+void::Locomotives::SendUpdate (Locomotive *loc) {
+ int lnum;
+ JSONParse jp;
+
+ if (locomotives == NULL) return;
+
+ for (lnum = 0; lnum < max; lnum++) {
+ if (loc == &locomotives[lnum]) {
+ jp.Clear();
+ jp.AddObject("locomotive",_GetJSON(lnum));
+ if(network) network->ChangeListPushToAll(jp.ToString());
+ break;
+ }
+ }
+
+}
+
+
int Locomotives::Loop() {
int lnum, i;
string way;
@@ -669,8 +783,7 @@ int Locomotives::Loop() {
}
}
else {
- // in here we need to put code for scheduled ways. ?
- printf ("%s:%d scheduled ways: not even started to work on this.\n", __FILE__, __LINE__);
+ SchedulerNextStep(loco);
}
}
diff --git a/server/locomotive.h b/server/locomotive.h
index 6002f1a..46d81ff 100644
--- a/server/locomotive.h
+++ b/server/locomotive.h
@@ -29,7 +29,7 @@ enum {
LOCO_OR_NOTHING = 0,
LOCO_OR_SEARCH, // search way (to next block and lock way)
LOCO_OR_PREPARE, // switch turnouts right way (one every 100ms)
- // if no turnout has to be set, continue
+ // if no turnout has to been set, continue
LOCO_OR_ONTHEWAY, // locomotive is on the way // maybe prepare next block?
// ASSIGN -> PREV, NEXT -> ASSIGN, NEXT <- (empty)
// propabely searching next block (if DEST is set)?
@@ -39,11 +39,6 @@ enum {
LOCO_OR_STOPWAIT // stopping
};
-struct s_LocoAuto {
- int onroute; // LOCO_OR_.....
- struct timeval waituntil; // wait until this time for next action (tournout, waiting station...)
-};
-
struct s_Locomotive {
char name[REFERENCENAME_LEN]; // name
char ifname[REFERENCENAME_LEN]; // ref. of interface
@@ -55,6 +50,7 @@ struct s_Locomotive {
int vmid; // speed - for normal trains (max for cargo trains, on automode)
int vfast; // speed - for normal trains
int vmax; // speed - maximum speed
+ char schedway[WAYDATA_LEN]; // scheduled way W:15,B:+B17,W30,B:-B21
// dynamic data
int speed; // current speed
@@ -64,6 +60,7 @@ struct s_Locomotive {
char blockprev[REFERENCENAME_LEN]; // prev block (mostly assigned block
char blockdest[REFERENCENAME_LEN]; // destination block
+ int sched_step; // on automode this is the scheduled way step
char auto_way[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname"
char auto_wayold[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname"
int auto_onroute; // LOCO_OR_....
@@ -71,6 +68,7 @@ struct s_Locomotive {
struct timeval auto_timenext; // timeval of the next active step
} typedef Locomotive;
+
class Locomotives {
private:
Locomotive *locomotives;
@@ -83,6 +81,8 @@ class Locomotives {
// not thread safe
JSONParse _GetJSON(int idx);
+ int SchedulerNextStep(Locomotive *loc); // automode, calculate next step
+ void SendUpdate(Locomotive *loc);
public:
Locomotives();
diff --git a/webinterface/gui/gui.css b/webinterface/gui/gui.css
index dd53169..d3d5d92 100644
--- a/webinterface/gui/gui.css
+++ b/webinterface/gui/gui.css
@@ -91,7 +91,7 @@ button {
input {
- border: 1px solid var(--input-bg-color);
+ border: 1px solid var(--input-fg-color);
background-color: var(--input-bg-color);
color: var(--input-fg-color);
font-family: "Lucida Console", Courier, monospace;
diff --git a/webinterface/locomotive.js b/webinterface/locomotive.js
index ff72366..e4fd1d6 100644
--- a/webinterface/locomotive.js
+++ b/webinterface/locomotive.js
@@ -19,6 +19,8 @@ var locomotives = [];
function locomotive_Update(data) {
for (var i = 0; i < locomotives.length; i++) {
if (data.name == locomotives[i].name) {
+ var loco_name = document.getElementById("locodet_name");
+
debug ("Update Locomotive:" + locomotives[i].name + " with Locomotive:" + data.name);
locomotives[i].name = data.name;
locomotives[i].ifname = data.ifname;
@@ -32,11 +34,18 @@ function locomotive_Update(data) {
locomotives[i].vmax = data.vmax;
locomotives[i].flags = data.flags;
if (data.blockassign) locomotives[i].blockassign = data.blockassign;
+ else locomotives[i].blockassign = "";
if (data.blockprev) locomotives[i].blockprev = data.blockprev;
+ else locomotives[i].blockprev = "";
if (data.blocknext) locomotives[i].blocknext = data.blocknext;
+ else locomotives[i].blocknext = "";
if (data.blockdest) locomotives[i].blockdest = data.blockdest;
+ else locomotives[i].blockdest = "";
+ if (data.schedway) locomotives[i].schedway = data.schedway;
+ else locomotives[i].schedway = "";
if (data.auto_way) locomotives[i].auto_way = data.auto_way;
- locodetail_setData(locomotives[i]);
+ if (loco_name.value == data.name) locodetail_setData(locomotives[i]);
+
lococtrl_setData(data);
return;
}
@@ -60,6 +69,7 @@ function locomotive_Update(data) {
blockdest: data.blockdest,
blocknext: data.blocknext,
blockprev: data.blockprev,
+ schedway: data.schedway,
auto_way: data.auto_way
});
@@ -152,16 +162,17 @@ function locodetail_show(loconame) {
Adress: \
Flags: \
\
- \
- \
\
+ \
|
\
+ |
\
+ \
+ \
+ \
+
\
\
\
\
@@ -226,7 +243,7 @@ function locodetail_show(loconame) {
//
// load default values
var res = { name: "", ifname: "", addr: "", flags: 0, steps: "",
- vmin: "20", vslow: "40", vmid:"60", vfast:"80", vmax:"100" };
+ vmin: "20", vslow: "40", vmid:"60", vfast:"80", vmax:"100", schedway: "" };
locodetail_setData(res);
if (loconame) {
@@ -450,6 +467,7 @@ function locodetail_setData(elm) {
var loco_blocknext = document.getElementById("locodet_blocknext");
var loco_blockprev = document.getElementById("locodet_blockprev");
var loco_auto_way = document.getElementById("locodet_auto_way");
+ var loco_schedway = document.getElementById("locodet_schedway");
if (elm) {
if (loco_name) loco_name.value = elm.name;
@@ -490,6 +508,8 @@ function locodetail_setData(elm) {
if (loco_blockdest) loco_blockdest.value = elm.blockdest;
if (loco_blocknext) loco_blocknext.value = elm.blocknext;
if (loco_blockprev) loco_blockprev.value = elm.blockprev;
+ if (loco_schedway && elm.schedway) loco_schedway.value = elm.schedway;
+ else loco_schedway.value = "";
if (loco_auto_way) loco_auto_way.value = elm.auto_way;
}
@@ -509,7 +529,7 @@ function locodetail_setData(elm) {
//
function locodetail_getData() {
var res = { name: "", ifname: "", addr: "", flags: 0, stepcode:"0",
- vmin: "20", vslow: "40", vmid:"60", vfast:"80", vmax:"100" };
+ vmin: "20", vslow: "40", vmid:"60", vfast:"80", vmax:"100", schedway: "" };
var codes = document.getElementsByName('STEPCODE');
for(var i = 0; i < codes.length; i++){
@@ -528,6 +548,7 @@ function locodetail_getData() {
var loco_vfast = document.getElementById("locodet_vfast");
var loco_vmax = document.getElementById("locodet_vmax");
var loco_speed = document.getElementById("locodet_speed");
+ var loco_schedway = document.getElementById("locodet_schedway");
if (loco_name) res.name = loco_name.value;
if (loco_ifname) res.ifname = loco_ifname.value;
@@ -539,6 +560,7 @@ function locodetail_getData() {
if (loco_vfast) res.vfast = loco_vfast.value;
if (loco_vmax) res.vmax = loco_vmax.value;
if (loco_speed) res.speed = loco_speed.speed;
+ if (loco_schedway) res.schedway = loco_schedway.value;
return res;
};
diff --git a/webinterface/serverinout.php b/webinterface/serverinout.php
index ace2bab..ed6238a 100644
--- a/webinterface/serverinout.php
+++ b/webinterface/serverinout.php
@@ -1,4 +1,8 @@