From b24a76aa72092692665a8981f52fc94cf8ebc6ce Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Wed, 27 Dec 2023 23:26:30 +0100 Subject: [PATCH] split block are working. fixed way finding issues. --- ChangeLog | 4 + server/locomotive.cc | 175 ++++++++++++++++++++++--------------- server/locomotive.h | 6 +- server/network.h | 1 + server/railway.cc | 2 +- server/server.h | 1 + server/session.cc | 18 ++++ webinterface/locomotive.js | 59 +++++++++---- 8 files changed, 175 insertions(+), 91 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd9d169..eee46b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-12-27: +- split blocks do work. +- fixed issues with the way finding routine + 2023-05-01: - another work on the split blocks. long trains wont go into split blocks. Some final checks are still needed to implement. diff --git a/server/locomotive.cc b/server/locomotive.cc index 078f6af..9924c2e 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -401,7 +401,7 @@ int Locomotives::Reset(string name) { for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) if (name.compare(locomotives[i].name) == 0) { debug (0, "Locomotives::Reset (Name:%s)", name.c_str()); - locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_RANDOM); + locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_AUTORANDOM | LOCO_F_AUTOSHED); locomotives[i].blockassign[0] = 0; locomotives[i].blockdest[0] = 0; locomotives[i].blockprev[0] = 0; @@ -435,7 +435,7 @@ int Locomotives::SetModeMan(string name) { for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) if (name.compare(locomotives[i].name) == 0) { debug (0, "Locomotives::SetMan (Name:%s)\n", name.c_str()); - locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_RANDOM); + locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_AUTORANDOM | LOCO_F_AUTOSHED); locomotives[i].auto_onroute = 0; locomotives[i].auto_way[0] = 0; locomotives[i].auto_wayold[0] = 0; @@ -462,7 +462,8 @@ int Locomotives::SetModeAutoMan(string name) { if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) { debug (0, "Locomotives::SetAutoMan (Name:%s)\n", name.c_str()); locomotives[i].flags |= LOCO_F_AUTOSTOP; - locomotives[i].flags &= ~LOCO_F_RANDOM; + locomotives[i].flags &= ~LOCO_F_AUTORANDOM; + locomotives[i].flags &= ~LOCO_F_AUTOSHED; jp.Clear(); jp.AddObject("locomotive",_GetJSON(i)); @@ -484,7 +485,8 @@ int Locomotives::SetModeAuto(string name) { if (name.compare(locomotives[i].name) == 0) { debug (0, "Locomotives::SetAuto (Name:%s)\n", name.c_str()); locomotives[i].flags |= LOCO_F_AUTO; - locomotives[i].flags &= ~LOCO_F_RANDOM; + locomotives[i].flags &= ~LOCO_F_AUTORANDOM; + locomotives[i].flags &= ~LOCO_F_AUTOSHED; jp.Clear(); jp.AddObject("locomotive",_GetJSON(i)); @@ -504,8 +506,33 @@ int Locomotives::SetModeAutoRand(string name) { Lock(); for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) { - debug (0, "Locomotives::SetRandom (Name:%s)\n", name.c_str()); - locomotives[i].flags |= LOCO_F_RANDOM; + debug (0, "Locomotives::SetAutoRandom (Name:%s)\n", name.c_str()); + locomotives[i].flags |= LOCO_F_AUTORANDOM; + locomotives[i].flags &= ~LOCO_F_AUTOSHED; + locomotives[i].flags &= ~LOCO_F_AUTOSTOP; + + jp.Clear(); + jp.AddObject("locomotive",_GetJSON(i)); + if(network) network->ChangeListPushToAll(jp.ToString()); + + break; + } + UnLock(); + + return 1; +}; + + +int Locomotives::SetModeAutoShed(string name) { + int i; + JSONParse jp; + + Lock(); + for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) + if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) { + debug (0, "Locomotives::SetAutoShed (Name:%s)\n", name.c_str()); + locomotives[i].flags |= LOCO_F_AUTOSHED; + locomotives[i].flags &= ~LOCO_F_AUTORANDOM; locomotives[i].flags &= ~LOCO_F_AUTOSTOP; jp.Clear(); @@ -758,65 +785,50 @@ int Locomotives::Loco_SearchAndLock(Locomotive *loco) { // // destination empty? true -> random // false -> find way to destination - if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TRYAGAIN) { - debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, loco->flags && LOCO_F_REVERSE ? 1 : 0); - timer_start(&loco->auto_timenext); + debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, (loco->flags & LOCO_F_REVERSE) ? 1 : 0); - // - // destination set? - need to find a random block? - if (loco->blockdest[0] == 0) { - if (loco->flags & LOCO_F_RANDOM) { - if (server->railways.FindRandomWay(loco->blockassign, loco->name, &way)) { - size_t pos, pos1; - if ((pos = way.find(",b:", 1)) != string::npos) { - if ((pos1 = way.find(",", pos+3)) != string::npos) { - strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN); - } - else strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); - strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); - if (server->railways.LockWay(way, loco->name) == 1) { - loco->auto_data = -1; - return 1; - } - server->railways.UnLockWay(way, loco->name); + // + // destination set? - need to find a random block? + if (loco->blockdest[0] == 0) { + if (loco->flags & LOCO_F_AUTORANDOM) { + if (server->railways.FindRandomWay(loco->blockassign, loco->name, &way)) { + size_t pos, pos1; + if ((pos = way.find(",b:", 1)) != string::npos) { + if ((pos1 = way.find(",", pos+3)) != string::npos) { + strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN); } - } - else { - // nothing found -> try reverse - if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) { - debug (0, "* Loco_SearchAndLock Reverse Loco %s", loco->name); - if (loco->blockassign[0] == '-') loco->blockassign[0] = '+'; - else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-'; - - if (loco->flags & LOCO_F_REVERSE) loco->flags &= ~LOCO_F_REVERSE; - else loco->flags |= LOCO_F_REVERSE; + else strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); + strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); + if (server->railways.LockWay(way, loco->name) == 1) { + loco->auto_data = -1; + return 1; } + server->railways.UnLockWay(way, loco->name); } } - else { - SchedulerNextStep(loco); - } } + else if (loco->flags & LOCO_F_AUTOSHED) { + SchedulerNextStep(loco); + } + } - // - // we assume a destination is set, and try to find a new way to the destination - else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) { - // try to lock way. - size_t pos, pos1; - debug (0, "Locomotives::Loop %s:%d Found Way:%s", __FILE__, __LINE__, way.c_str()); - if ((pos = way.find(",b:", 1)) != string::npos) { - if ((pos1 = way.find(",", pos+3)) != string::npos) { - strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN); - } - else strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); - strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); - if (server->railways.LockWay(way, loco->name) == 1) { - loco->auto_data = -1; - return 1; - } - server->railways.UnLockWay(way, loco->name); - timer_start(&loco->auto_timenext); + // + // we assume a destination is set, and try to find a new way to the destination + else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) { + // try to lock way. + size_t pos, pos1; + debug (0, "Locomotives::Loop %s:%d Found Way:%s", __FILE__, __LINE__, way.c_str()); + if ((pos = way.find(",b:", 1)) != string::npos) { + if ((pos1 = way.find(",", pos+3)) != string::npos) { + strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN); + } + else strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); + strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); + if (server->railways.LockWay(way, loco->name) == 1) { + loco->auto_data = -1; + return 1; } + server->railways.UnLockWay(way, loco->name); } } @@ -954,9 +966,12 @@ int Locomotives::Loco_BlockEnterStop(Locomotive *loco) { s_stop = server->blocks.GetSensorStop(dir_reverse, block, loco->flags); s_slow = server->blocks.GetSensorSlow(dir_reverse, block, loco->flags); s_enter = server->blocks.GetSensorEnter(dir_reverse, block, loco->flags); - if (server->sensors.GetActive(s_stop) == 1) { - debug (0, "Locomotives::Loop EnterBlockStop '%s' UnLockWay\n", loco->name); + debug (0, "Locomotives::Loop BlockEnterStop '%s' UnLockWay\n", loco->name); + debug (0, "* %s,%d Sensor Enter '%s' = %d", __FILE__, __LINE__, s_enter.c_str(), server->sensors.GetActive(s_enter)); + debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow)); + debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop)); + SetSpeed(loco->name, 0); loco->auto_onroute = LOCO_OR_STOPWAIT; server->railways.UnLockWay(loco->auto_wayold, loco->name); @@ -1075,7 +1090,7 @@ int Locomotives::Loop() { continue; } else { - debug (0, "%s:%d Locomotive [%s] is doing NOTHING", __FILE__, __LINE__, loco->name); + debug (0, "%s:%d Locomotive [%s] is doing NOTHING", __FILE__, __LINE__, loco->name); timer_start(&loco->auto_timenext); loco->auto_onroute = LOCO_OR_SEARCH; } @@ -1089,17 +1104,37 @@ int Locomotives::Loop() { SetModeMan(loco->name); continue; } - if (strcmp(loco->blockassign, loco->blockdest) == 0) { - loco->blockdest[0] = 0; - debug (0, "* Locomotive '%s' DEST == ASSING", loco->name); - jp.Clear(); - jp.AddObject("locomotive",_GetJSON(lnum)); - if(network) network->ChangeListPushToAll(jp.ToString()); - } - // try to find and lock a way - if (Loco_SearchAndLock(loco)) { - loco->auto_onroute = LOCO_OR_PREPARE; + if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TRYAGAIN) { + timer_start(&loco->auto_timenext); + + if (strcmp(loco->blockassign, loco->blockdest) == 0) { + loco->blockdest[0] = 0; + debug (0, "* Locomotive '%s' DEST == ASSING", loco->name); + jp.Clear(); + jp.AddObject("locomotive",_GetJSON(lnum)); + if(network) network->ChangeListPushToAll(jp.ToString()); + } + + // try to find and lock a way + if (Loco_SearchAndLock(loco)) { + loco->auto_onroute = LOCO_OR_PREPARE; + } + else { + // nothing found -> try reverse + if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) { + debug (0, "* Loco_SearchAndLock Reverse Loco %s", loco->name); + if (loco->blockassign[0] == '-') loco->blockassign[0] = '+'; + else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-'; + + if (loco->flags & LOCO_F_REVERSE) loco->flags &= ~LOCO_F_REVERSE; + else loco->flags |= LOCO_F_REVERSE; + + jp.Clear(); + jp.AddObject("locomotive",_GetJSON(lnum)); + if(network) network->ChangeListPushToAll(jp.ToString()); + } + } } } diff --git a/server/locomotive.h b/server/locomotive.h index bfd78cc..dd8a597 100644 --- a/server/locomotive.h +++ b/server/locomotive.h @@ -10,8 +10,9 @@ #define LOCO_F_CANREVERSE 0x0020 #define LOCO_F_SHORTTRAIN 0x0040 #define LOCO_F_AUTO 0x0100 -#define LOCO_F_RANDOM 0x0200 -#define LOCO_F_AUTOSTOP 0x0400 +#define LOCO_F_AUTOSHED 0x0200 +#define LOCO_F_AUTORANDOM 0x0400 +#define LOCO_F_AUTOSTOP 0x0800 #define LOCO_TO_TURNOUT (50+TURNOUT_DEFAULT_ACTIVETIMEOUT) #define LOCO_TO_TRYAGAIN (1000) @@ -106,6 +107,7 @@ class Locomotives { int SetModeAutoMan(string name); int SetModeAuto(string name); int SetModeAutoRand(string name); + int SetModeAutoShed(string name); int SetSpeedFromBus (string ifname, int addr, int speed); int SetFunctionFromBus (string ifname, int addr, int func); int SetDestination (string name, string block, int direction); diff --git a/server/network.h b/server/network.h index 51957e7..8d1f676 100644 --- a/server/network.h +++ b/server/network.h @@ -71,6 +71,7 @@ private: void SetJSONLocoAutoMan(JSONParse *jp); void SetJSONLocoAuto(JSONParse *jp); void SetJSONLocoAutoRand(JSONParse *jp); + void SetJSONLocoAutoShed(JSONParse *jp); void BlockJSONOff(JSONParse *jp); void BlockJSONClear(JSONParse *jp); diff --git a/server/railway.cc b/server/railway.cc index 51a8684..931aa74 100644 --- a/server/railway.cc +++ b/server/railway.cc @@ -711,7 +711,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf } } - if (found == 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { + if (conector_found == 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { fd_pos.enterfrom = -1; fd_pos.x = -1; fd_pos.y = -1; diff --git a/server/server.h b/server/server.h index 8ffcab2..d4e2a9b 100644 --- a/server/server.h +++ b/server/server.h @@ -168,6 +168,7 @@ public: int LocomotiveSetAuto(string name) { return locomotives.SetModeAuto(name); }; int LocomotiveSetAutoMan(string name) { return locomotives.SetModeAutoMan(name); }; int LocomotiveSetAutoRand(string name) { return locomotives.SetModeAutoRand(name); }; + int LocomotiveSetAutoShed(string name) { return locomotives.SetModeAutoShed(name); }; int LocomotiveTest(string name) { return locomotives.Test(name); }; ///////////////////////////////////////// diff --git a/server/session.cc b/server/session.cc index 95f5097..3987388 100644 --- a/server/session.cc +++ b/server/session.cc @@ -148,6 +148,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) { else if (command.compare("locomotivesetautorand") == 0) { SetJSONLocoAutoRand(jin); } + else if (command.compare("locomotivesetautoshed") == 0) { + SetJSONLocoAutoShed(jin); + } else if (command.compare("locomotivereset") == 0) { SetJSONLocoReset(jin); } @@ -616,6 +619,21 @@ void Session::SetJSONLocoAutoRand(JSONParse *jp) { }; +void Session::SetJSONLocoAutoShed(JSONParse *jp) { + string loco; + JSONParse jout; + + jp->GetValue("locomotive", &loco); + + server->LockThread(); + server->LocomotiveSetAutoShed(loco); + jout.Clear(); + jout.AddObject("locomotive", server->LocomotiveGetJSON(loco)); + if (network) network->ChangeListPushToAll(jout.ToString()); + server->UnLockThread(); +}; + + // // add new Turnout diff --git a/webinterface/locomotive.js b/webinterface/locomotive.js index f7223cf..f489799 100644 --- a/webinterface/locomotive.js +++ b/webinterface/locomotive.js @@ -7,8 +7,9 @@ const LOCO_F_CARGO = 0x0010; const LOCO_F_CANREVERSE = 0x0020; const LOCO_F_SHORTTRAIN = 0x0040; const LOCO_F_AUTO = 0x0100; -const LOCO_F_RANDOM = 0x0200; -const LOCO_F_AUTOSTOP = 0x0400; +const LOCO_F_AUTOSHED = 0x0200; +const LOCO_F_AUTORANDOM = 0x0400; +const LOCO_F_AUTOSTOP = 0x0800; var locomotives = []; @@ -150,7 +151,7 @@ function locodetail_show(loconame) { if (!win) { console.log ("loco_showdetail create window"); - win = gWindowCreate("locodetail", "Locomotive", 450, 500, + win = gWindowCreate("locodetail", "Locomotive", 450, 550, "
\ Name: \
\ @@ -164,7 +165,8 @@ function locodetail_show(loconame) {

\
\ \ \ - \ - \ + \ + \ + \ + \ + \ \
\
\ -
\ +
\ +
\
\
\
\ @@ -461,7 +463,8 @@ function locodetail_setData(elm) { var loco_short = document.getElementById("locodet_short"); var loco_cargo = document.getElementById("locodet_cargo"); var loco_auto = document.getElementById("locodet_auto"); - var loco_random = document.getElementById("locodet_random"); + var loco_autorandom = document.getElementById("locodet_autorandom"); + var loco_autoshed = document.getElementById("locodet_autoshed"); var loco_blockassign = document.getElementById("locodet_blockassign"); var loco_blockdest = document.getElementById("locodet_blockdest"); var loco_blocknext = document.getElementById("locodet_blocknext"); @@ -500,16 +503,20 @@ function locodetail_setData(elm) { if (Number(elm.flags) & LOCO_F_AUTO) loco_auto.checked = true; else loco_auto.checked = false; } - if (loco_random) { - if (Number(elm.flags) & LOCO_F_RANDOM) loco_random.checked = true; - else loco_random.checked = false; + if (loco_autorandom) { + if (Number(elm.flags) & LOCO_F_AUTORANDOM) loco_autorandom.checked = true; + else loco_autorandom.checked = false; + } + if (loco_autoshed) { + if (Number(elm.flags) & LOCO_F_AUTOSHED) loco_autoshed.checked = true; + else loco_autoshed.checked = false; } if (loco_blockassign) loco_blockassign.value = elm.blockassign; 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 = ""; + else if (loco_shedway) loco_schedway.value = ""; if (loco_auto_way) loco_auto_way.value = elm.auto_way; } @@ -675,8 +682,11 @@ function lococtrl_show(name) {
\ \ @@ -697,7 +707,8 @@ function lococtrl_show(name) { gAddEventListener("lococtrl_"+name+"_btnman", 'click', lococtrl_cb_btnman); gAddEventListener("lococtrl_"+name+"_btnstopman", 'click', lococtrl_cb_btnstopman); gAddEventListener("lococtrl_"+name+"_btnauto", 'click', lococtrl_cb_btnauto); - gAddEventListener("lococtrl_"+name+"_btnrand", 'click', lococtrl_cb_btnrand); + gAddEventListener("lococtrl_"+name+"_btnautorand", 'click', lococtrl_cb_btnautorand); + gAddEventListener("lococtrl_"+name+"_btnautoshed", 'click', lococtrl_cb_btnautoshed); gAddEventListener("lococtrl_"+name+"_RANGE", 'click', lococtrl_speed); gAddEventListener("lococtrl_"+name+"_REVBTN", 'click', lococtrl_reverse); @@ -710,7 +721,6 @@ function lococtrl_show(name) { }; - function lococtrl_cb_btnreset() { var name = getTextBetween(this.id, "lococtrl_", "_btnreset"); var request = { command: "locomotivereset", locomotive: name }; @@ -742,13 +752,20 @@ function lococtrl_cb_btnauto() { }; -function lococtrl_cb_btnrand() { - var name = getTextBetween(this.id, "lococtrl_", "_btnauto"); +function lococtrl_cb_btnautorand() { + var name = getTextBetween(this.id, "lococtrl_", "_btnautorand"); var request = { command: "locomotivesetautorand", locomotive: name }; serverinout (request, serverinout_defaultCallback); }; +function lococtrl_cb_btnautoshed() { + var name = getTextBetween(this.id, "lococtrl_", "_btnautoshed"); + var request = { command: "locomotivesetautoshed", locomotive: name }; + serverinout (request, serverinout_defaultCallback); +}; + + function lococtrl_reverse() { var name = getTextBetween(this.id, "lococtrl_", "_REVBTN"); var reverse; @@ -813,12 +830,14 @@ function lococtrl_setData(data) { var range = document.getElementById("lococtrl_"+data.name+"_RANGE"); var reverse = document.getElementById("lococtrl_"+data.name+"_REVBTN"); var cbauto = document.getElementById("lococtrl_"+data.name+"_cbauto"); - var cbrand = document.getElementById("lococtrl_"+data.name+"_cbrand"); + var cbautorand = document.getElementById("lococtrl_"+data.name+"_cbautorand"); + var cbautoshed = document.getElementById("lococtrl_"+data.name+"_cbautoshed"); var cbmanstop = document.getElementById("lococtrl_"+data.name+"_cbstopman"); var btnman = document.getElementById("lococtrl_"+data.name+"_btnman"); var btnautostop = document.getElementById("lococtrl_"+data.name+"_btnstopman"); var btnauto = document.getElementById("lococtrl_"+data.name+"_btnauto"); - var btnautorand = document.getElementById("lococtrl_"+data.name+"_btnrand"); + var btnautorand = document.getElementById("lococtrl_"+data.name+"_btnautorand"); + var btnautoshed = document.getElementById("lococtrl_"+data.name+"_btnautoshed"); if (range && reverse) { console.log ("lococtrl: " + data.name + " speed:" + data.speed + " vmax:" + @@ -827,24 +846,28 @@ function lococtrl_setData(data) { else reverse.innerHTML = "FWD"; cbauto.checked = (data.flags & LOCO_F_AUTO); - cbrand.checked = (data.flags & LOCO_F_RANDOM); + cbautorand.checked = (data.flags & LOCO_F_AUTORANDOM); + cbautoshed.checked = (data.flags & LOCO_F_AUTOSHED); cbmanstop.checked = (data.flags & LOCO_F_AUTOSTOP); if (data.flags & LOCO_F_AUTOSTOP) { btnman.disabled = false; btnauto.disabled = true; btnautorand.disabled = true; + btnautoshed.disabled = true; btnautostop.disabled = true; } else if (data.flags & LOCO_F_AUTO) { btnman.disabled = true; btnautorand.disabled = false; + btnautoshed.disabled = false; btnautostop.disabled = false; } else { btnman.disabled = true; btnautorand.disabled = true; btnautostop.disabled = true; + btnautoshed.disabled = true; btnauto.disabled = false; }