From d4efc193c79be4ba5b1c92f6484e698d3ccc4f0b Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Mon, 1 May 2023 22:32:58 +0200 Subject: [PATCH] another work on the split blocks. long trains wont go into split blocks. Some final checks are still needed --- ChangeLog | 4 ++ server/block.cc | 18 ++++++ server/block.h | 1 + server/interfaces.cc | 19 ++++-- server/locomotive.cc | 2 +- server/railway.cc | 131 +++++++++++++++++++++++++++++++++-------- server/railway.h | 3 +- webinterface/block.js | 31 ++++++---- webinterface/sensor.js | 29 +++++---- 9 files changed, 183 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23d3642..cd9d169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-05-01: +- another work on the split blocks. long trains wont go into split blocks. Some final + checks are still needed to implement. + 2023-04-02: - fixed: track infomation is fixed. - removed unneded debug file diff --git a/server/block.cc b/server/block.cc index c03ef50..8d6bbf0 100644 --- a/server/block.cc +++ b/server/block.cc @@ -110,6 +110,7 @@ Block Blocks::GetBlockFromJSON(JSONParse *j) { string s; bl.name[0] = 0; + bl.secondblock[0] = 0; bl.flags = 0; bl.lockedby[0] = 0; @@ -150,6 +151,7 @@ Block Blocks::GetBlockFromJSON(JSONParse *j) { s = ""; if (j->GetValue("sensor_stop_1", &s)) strncpy (bl.s_stop[1], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_shortstop_0", &s)) strncpy (bl.s_shortstop[0], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_shortstop_1", &s)) strncpy (bl.s_shortstop[1], s.c_str(), REFERENCENAME_LEN); + s = ""; if (j->GetValue("secondblock", &s)) strncpy (bl.secondblock, s.c_str(), REFERENCENAME_LEN); printf ("%s:%d block: %s flags: %d\n", __FILE__, __LINE__, bl.name, bl.flags); return bl; @@ -298,6 +300,22 @@ string Blocks::GetLockedby (string blname) { }; +string Blocks::GetSecondBlock(string block) { + Block *bl = NULL; + string sb; + + Lock(); + if ((bl = FindBlock(block)) != NULL) { + sb = bl->secondblock; + UnLock(); + return sb; + } + UnLock(); + + return ""; +} + + Block* Blocks::FindBlock(string name) { Block *bl = NULL; diff --git a/server/block.h b/server/block.h index b4a8cf6..d0ed9fd 100644 --- a/server/block.h +++ b/server/block.h @@ -94,6 +94,7 @@ class Blocks { string GetSensorStop (int direction, string blname); string GetSensorShortStop (int direction, string blname); int GetFlags (string blname); + string GetSecondBlock(string block); int SetLockedby (string blname, string lockedby, int lock_onoff); string GetLockedby (string blname); diff --git a/server/interfaces.cc b/server/interfaces.cc index f5858cc..c13faaf 100644 --- a/server/interfaces.cc +++ b/server/interfaces.cc @@ -201,10 +201,21 @@ void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) { LockThread(); debug (0, "%s:%d Interfaces::SetTurnout Name:%s active:%d Output%d", __FILE__, __LINE__, t->name, active, motoractive); - for (i = 0; i < max; i++) if (interfaces[i] != NULL) { - if (!interfaces[i]->IsConnected()) interfaces[i]->Connect(); - if (strncmp(t->ifname, interfaces[i]->name, REFERENCENAME_LEN) == 0) - interfaces[i]->SetTurnout(t, active, motoractive); + // + // if the interfacename is debug ... simulate a change in the turnout + // + if (strncmp(t->ifname, "DEBUG", REFERENCENAME_LEN) == 0) { + if (active) t->flags |= TURNOUT_F_ACTIVE; + else t->flags &= ~TURNOUT_F_ACTIVE; + + server->TurnoutAddrMode(t->ifname, t->addr, active); + } + else { + for (i = 0; i < max; i++) if (interfaces[i] != NULL) { + if (!interfaces[i]->IsConnected()) interfaces[i]->Connect(); + if (strncmp(t->ifname, interfaces[i]->name, REFERENCENAME_LEN) == 0) + interfaces[i]->SetTurnout(t, active, motoractive); + } } UnLockThread(); diff --git a/server/locomotive.cc b/server/locomotive.cc index 67eee30..2ffe658 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -306,7 +306,7 @@ int Locomotives::SetDestination (string name, string block, int direction) { debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)", name.c_str(), block.c_str(), direction); blflags = server->blocks.GetFlags(block); - if ((blflags & BLOCK_F_SHORT) && !(locomotives[i].flags & LOCO_F_SHORTTRAIN)) break; + if ((blflags & BLOCK_F_SHORT) && !(locomotives[i].flags & LOCO_F_SHORTTRAIN) && !(blflags & BLOCK_F_SPLIT)) break; if ((blflags & BLOCK_F_ENDSTATION) && !(locomotives[i].flags & LOCO_F_CANREVERSE)) break; if ((blflags & BLOCK_F_ONLYCARGO) && !(locomotives[i].flags & LOCO_F_CARGO)) break; if ((blflags & BLOCK_F_ONLYPASSENGER) && (locomotives[i].flags & LOCO_F_CARGO)) break; diff --git a/server/railway.cc b/server/railway.cc index e0f7392..40371f8 100644 --- a/server/railway.cc +++ b/server/railway.cc @@ -41,7 +41,7 @@ int Railways::UnLock() { // data must be mutex looked before use struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype) { struct s_findway_data np = { x: -1, y: -1, enterfrom: -1, oldx: pos.x, oldy:pos.y, - oldenterfrom: pos.enterfrom, parma: pos.parma, + oldenterfrom: pos.enterfrom, way: pos.way }; // newpos if (dirtype == 1) { @@ -501,6 +501,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri int found = 0; int locoflags = server->locomotives.GetFlags(lockedfor); + debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", blockstart.c_str(), blockend.c_str(), lockedfor.c_str()); + // check blocklen if (blockstart.length() <= 3 || blockend.length() <= 3) return 0; @@ -517,7 +519,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_end.x = fd_start.x = -1; fd_end.y = fd_start.y = -1; fd_end.enterfrom = fd_start.enterfrom = -1; - fd_end.parma = fd_start.parma = -1; if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) { if (Get(fd_start.x, fd_start.y).dir == 1) { @@ -531,7 +532,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_start.way = "b:" + blockstart; fd_data[GetRIdx(fd_start.x, fd_start.y)].e = (1 << fd_start.enterfrom); fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1; - fd_start.parma = 1; } else { debug (0, "Railway::FindWay could not find startblock (%s).", blockstart.c_str()); @@ -617,9 +617,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) { fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; rnext = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; - if (rnext->lockedby[0] != 0) { + if (rnext->lockedby[0] != 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { fd_pos.enterfrom = -1; fd_pos.x = -1; fd_pos.y = -1; @@ -630,19 +629,23 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri else if (rpos->type == RAILWAY_TURNOUT) { fd_tmp = NextPos(fd_pos, rpos->altdir); fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":1"; - fd_tmp.parma += 10; // 10 bad point for using the turnout fd_list.push_back(fd_tmp); fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0"; - fd_pos.parma++; + if (!_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { + fd_pos.enterfrom = -1; + fd_pos.x = -1; + fd_pos.y = -1; + fd_pos.way = ""; + } + else fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0"; } else if (rpos->type == RAILWAY_CONNECTOR) { - int found = 0; + int conector_found = 0; x = -1; y = -1; - while (found == 0 && _FindReference(&x, &y, rpos->name) == 1) { + while (conector_found == 0 && _FindReference(&x, &y, rpos->name) == 1) { if (fd_pos.x != x || fd_pos.y != y) { fd_pos.oldx = fd_pos.x; fd_pos.oldy = fd_pos.y; @@ -651,13 +654,13 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_pos.y = y; rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; - found = 1; + + conector_found = 1; break; } } - if (found == 0) { + if (found == 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { fd_pos.enterfrom = -1; fd_pos.x = -1; fd_pos.y = -1; @@ -671,7 +674,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri if ((server->blocks.IsOff(rpos->name) || ((blflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) || - ((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN)) || + ((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) && + !_SplitBlockIsFreeAndAllowed(lockedfor, locoflags, rpos->name)) || ((blflags & BLOCK_F_ONLYCARGO) && !(locoflags & LOCO_F_CARGO)) || ((blflags & BLOCK_F_ONLYPASSENGER) && (locoflags & LOCO_F_CARGO)))) { fd_pos.enterfrom = -1; @@ -688,7 +692,12 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri else fd_pos.way += (string)",b:-:" + (string)rpos->name; fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; + if (!_NextPosIsValid(lockedfor, locoflags, &fd_pos)) { + fd_pos.enterfrom = -1; + fd_pos.x = -1; + fd_pos.y = -1; + fd_pos.way = ""; + } } else { fd_pos.enterfrom = -1; @@ -727,6 +736,85 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri }; +/* + * check if the position in fwd.x|y is valid for the loco. The check will only done on + * RAILWAY_BLOCK types. It will also check if the block is free. + */ +int Railways::_NextPosIsValid(string loconame, int locoflags, struct s_findway_data *fwd) { + int bflags = -1; + Railway *rpos = NULL; + + rpos = &railways[GetRIdx(fwd->x, fwd->y)]; + bflags = server->blocks.GetFlags(rpos->name); + + if (rpos->type != RAILWAY_BLOCK) return 1; + + if (server->blocks.IsOff(rpos->name)) return 0; + if ((bflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) return 0; + if ((bflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) && + !_SplitBlockIsFreeAndAllowed(loconame, locoflags, rpos->name)) return 0; + if ((bflags & BLOCK_F_ONLYCARGO) && !(locoflags & LOCO_F_CARGO)) return 0; + if ((bflags & BLOCK_F_ONLYPASSENGER) && (locoflags & LOCO_F_CARGO)) return 0; + + return 1; +}; + + +/* + * check if this is a split block, and if it can be entered + * all needed elements must be unlocked to return 1. + * if the loco is a short train return 0 + */ +int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block) { + string pblock; + string nblock; + int bflags = server->blocks.GetFlags(block); + int nblockflags = 0; + int pblockflags = 0; + int x1, y1, x2, y2, dx = 0, dy = 0; + + debug (0, "Railway::_SplitBlockIsFreeAndAllowed loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str()); + + if (locoflags & LOCO_F_SHORTTRAIN) return 0; + if ((locoflags & !LOCO_F_SHORTTRAIN) && (bflags & !BLOCK_F_SPLIT)) return 0; + + // + // read negative the positive block flags + if (bflags & BLOCK_F_SPLITPOS) { + pblockflags = bflags; + pblock = block; + nblock = server->blocks.GetSecondBlock(block); + if (nblock.length() == 0) return 0; + nblockflags = server->blocks.GetFlags(nblock); + } + else { + nblockflags = bflags; + nblock = block; + pblock = server->blocks.GetSecondBlock(block); + if (pblock.length() == 0) return 0; + pblockflags = server->blocks.GetFlags(pblock); + } + + // + // check if blockflags are setup right and the blocks are free + if (!(nblockflags & BLOCK_F_SPLIT) && (nblockflags & BLOCK_F_SPLITPOS)) return 0; + if (!(pblockflags & BLOCK_F_SPLIT) && !(pblockflags & BLOCK_F_SPLITPOS)) return 0; + if (server->blocks.GetLockedby(nblock).length() != 0) return 0; + if (server->blocks.GetLockedby(pblock).length() != 0) return 0; + + // check the way between the blocks + if (_FindReference(&x1, &y1, pblock) == 0) return 0; + if (_FindReference(&x2, &y2, nblock) == 0) return 0; + debug (0, "Railway::_SplitBlockIsFreeAndAllowed p pos(%d,%d) n pos(%d,%d)", x1, y1, x2, y2); +// if (x1 == x2 ) +// do { +// +// } while +// + return 0; +} + + int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { // direction 0 ... RIGHT and DOWN // direction 1 ... LEFT and UP @@ -742,7 +830,8 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { int found = 0; int locoflags = server->locomotives.GetFlags(lockedfor); - debug (0, "Railway::FindRandomWay"); + debug (0, "Railway::FindRandomWay - disabled for now - needs to be rewritten"); + return 0; // check blocklen if (blockstart.length() <= 3) return 0; @@ -760,7 +849,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { fd_end.x = fd_start.x = -1; fd_end.y = fd_start.y = -1; fd_end.enterfrom = fd_start.enterfrom = -1; - fd_end.parma = fd_start.parma = -1; if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) { if (Get(fd_start.x, fd_start.y).dir == 1) { @@ -774,7 +862,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { fd_start.way = "b:" + blockstart; fd_data[GetRIdx(fd_start.x, fd_start.y)].e = (1 << fd_start.enterfrom); fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1; - fd_start.parma = 1; } else { debug (0, "Railway::FindRandomWay could not find startblock (%s).", blockstart.c_str()); @@ -831,7 +918,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) { fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; rnext = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; if (rnext->lockedby[0] != 0) { fd_pos.enterfrom = -1; @@ -846,20 +932,16 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { if ((rand() & 1) == 1) { fd_tmp = NextPos(fd_pos, rpos->altdir); fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":1"; - fd_tmp.parma += 10; // 10 bad point for using the turnout fd_list.push_back(fd_tmp); fd_pos = NextPos(fd_pos, rpos->dir); fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0"; - fd_pos.parma++; } else { fd_tmp = NextPos(fd_pos, rpos->dir); fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":0"; - fd_tmp.parma += 10; // 10 bad point for using the turnout fd_list.push_back(fd_tmp); fd_pos = NextPos(fd_pos, rpos->altdir); fd_pos.way += (string)",t:" + (string)rpos->name + (string)":1"; - fd_pos.parma++; } } @@ -877,7 +959,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { fd_pos.y = y; rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; found = 1; break; } @@ -980,7 +1061,6 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) { end.x = start.x = -1; end.y = start.y = -1; end.enterfrom = start.enterfrom = -1; - end.parma = start.parma = -1; if ((pos1 = way.find("b:", 0)) == string::npos) return 0; if ((pos2 = way.find(",", pos1+1)) == string::npos) return 0; @@ -1128,7 +1208,6 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) { pos.y = y; r = &railways[GetRIdx(pos.x, pos.y)]; pos = NextPos(pos, r->dir); - pos.parma++; found = 1; break; } diff --git a/server/railway.h b/server/railway.h index df259b7..1470087 100644 --- a/server/railway.h +++ b/server/railway.h @@ -74,7 +74,6 @@ struct s_findway_data { int oldx; int oldy; int oldenterfrom; - int parma; string way; }; @@ -100,6 +99,8 @@ class Railways { void _New (int w, int h); void DebugPrintFindWay(struct s_findway_map *fw); int _FindReference(int *x, int *y, string name); + int _SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block); + int _NextPosIsValid(string loconame, int locoflags, struct s_findway_data *fwd); public: Railways(); diff --git a/webinterface/block.js b/webinterface/block.js index c2c0222..f8d3dfa 100644 --- a/webinterface/block.js +++ b/webinterface/block.js @@ -22,14 +22,15 @@ function block_Update(blockdata) { blocks[i].name = blockdata.name; blocks[i].flags = blockdata.flags; blocks[i].lockedby = blockdata.lockedby; - blocks[i].sensor_stop_0 = blockdata.sensor_stop_0, - blocks[i].sensor_shortstop_0 = blockdata.sensor_shortstop_0, - blocks[i].sensor_slow_0 = blockdata.sensor_slow_0, - blocks[i].sensor_enter_0 = blockdata.sensor_enter_0, - blocks[i].sensor_stop_1 = blockdata.sensor_stop_1, - blocks[i].sensor_shortstop_1 = blockdata.sensor_shortstop_1, - blocks[i].sensor_slow_1 = blockdata.sensor_slow_1, - blocks[i].sensor_enter_1 = blockdata.sensor_enter_1, + blocks[i].sensor_stop_0 = blockdata.sensor_stop_0; + blocks[i].sensor_shortstop_0 = blockdata.sensor_shortstop_0; + blocks[i].sensor_slow_0 = blockdata.sensor_slow_0; + blocks[i].sensor_enter_0 = blockdata.sensor_enter_0; + blocks[i].sensor_stop_1 = blockdata.sensor_stop_1; + blocks[i].sensor_shortstop_1 = blockdata.sensor_shortstop_1; + blocks[i].sensor_slow_1 = blockdata.sensor_slow_1; + blocks[i].sensor_enter_1 = blockdata.sensor_enter_1; + blocks[i].secondblock = blockdata.secondblock; blockdetail_setData(blocks[i]); return; } @@ -48,7 +49,8 @@ function block_Update(blockdata) { sensor_enter_1: blockdata.sensor_enter_1, sensor_slow_1: blockdata.sensor_slow_1, sensor_stop_1: blockdata.sensor_stop_1, - sensor_shortstop_1: blockdata.sensor_shortstop_1 + sensor_shortstop_1: blockdata.sensor_shortstop_1, + secondblock: blockdata.secondblock }); }; @@ -232,8 +234,10 @@ function blockdetail_show(name, create) { \ \ \ - \ - \ + second block:"; + innerHTML += ""; + innerHTML += " \ + \ \ \
Automatic Mode \ @@ -390,6 +394,7 @@ function blockdetail_setData(elm) { var sensor_stop_1 = document.getElementById("blockdet_sensor_stop_1"); var sensor_shortstop_1 = document.getElementById("blockdet_sensor_shortstop_1"); var lockedby = document.getElementById("blockdet_lockedby"); + var secondblock = document.getElementById("blockdet_secondblock"); if (elm) { if (name) name.value = elm.name; @@ -410,6 +415,7 @@ function blockdetail_setData(elm) { if (sensor_slow_1) sensor_slow_1.value = elm.sensor_slow_1; if (sensor_stop_1) sensor_stop_1.value = elm.sensor_stop_1; if (sensor_shortstop_1) sensor_shortstop_1.value = elm.sensor_shortstop_1; + if (secondblock) secondblock.value = elm.secondblock; if (lockedby) lockedby.value = elm.lockedby; } }; @@ -439,6 +445,7 @@ function blockdetail_getData() { var sensor_slow_1 = document.getElementById("blockdet_sensor_slow_1"); var sensor_stop_1 = document.getElementById("blockdet_sensor_stop_1"); var sensor_shortstop_1 = document.getElementById("blockdet_sensor_shortstop_1"); + var secondblock = document.getElementById("blockdet_secondblock"); if (name) res.name = name.value; @@ -478,6 +485,8 @@ function blockdetail_getData() { if (sensor_stop_1) res.sensor_stop_1 = sensor_stop_1.value; if (sensor_shortstop_1) res.sensor_shortstop_1 = sensor_shortstop_1.value; + if (secondblock) res.secondblock = secondblock.value; + return res; }; diff --git a/webinterface/sensor.js b/webinterface/sensor.js index 882f3e7..9194af7 100644 --- a/webinterface/sensor.js +++ b/webinterface/sensor.js @@ -88,7 +88,6 @@ function sensor_IsActive(name) { - function sensordetail_show(name, create) { var win = document.getElementById("sensordetail"); @@ -323,22 +322,28 @@ function sensorlist_cb_close () { // *********************************************************************************************** // *********************************************************************************************** // sensor contextmenu: show a context menu for the sensor -// +// this is only if the INTERFACE name is set tu DEBUG // *********************************************************************************************** // *********************************************************************************************** function sensor_contextmenu(name) { let innerhtml = ""; - innerhtml = "
"; - innerhtml += "
"; - innerhtml += "
"; - innerhtml += "
"; - - gContextmenuCreate(name, innerhtml); - - gAddEventListener("contextbox_On", 'click', sensor_ctxmenu_On); - gAddEventListener("contextbox_Off", 'click', sensor_ctxmenu_Off); - gAddEventListener("contextbox_Close", 'click', gContextmenuClose); + for (var i = 0; i < sensors.length; i++) { + if (name == sensors[i].name) { + if (sensors[i].ifname == "DEBUG") { + innerhtml = "
"; + innerhtml += "
"; + innerhtml += "
"; + innerhtml += "
"; + + gContextmenuCreate(name, innerhtml); + + gAddEventListener("contextbox_On", 'click', sensor_ctxmenu_On); + gAddEventListener("contextbox_Off", 'click', sensor_ctxmenu_Off); + gAddEventListener("contextbox_Close", 'click', gContextmenuClose); + } + } + } };