From 5e1142e4e2b878bd4f596a9c2edc1594fd265192 Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Sun, 26 Dec 2021 18:35:39 +0100 Subject: [PATCH] adding support for buttons, fixed serval issues with the display. Fixed all compile warnings. --- server/Makefile | 2 +- server/interface-z21.cc | 23 ++++----- server/interface-z21.h | 2 +- server/interface.cc | 31 ++++++++---- server/interface.h | 2 +- server/json.cc | 4 +- server/locomotive.cc | 7 ++- server/main.cc | 2 - server/modelbahn-cgi.cc | 2 +- server/network.cc | 7 +-- server/railway.cc | 13 ++--- server/sensor.cc | 1 + server/server-loadsave.cc | 2 +- server/server.cc | 24 +++++---- server/session.cc | 6 --- server/turnout.cc | 74 +++++++++++++++++++-------- server/turnout.h | 7 +-- webinterface/layout.css | 2 + webinterface/railways.js | 104 +++++++++++++++++++++++++++++++++----- webinterface/track.js | 22 +++++++- 20 files changed, 228 insertions(+), 109 deletions(-) diff --git a/server/Makefile b/server/Makefile index 788f7df..840ddd8 100644 --- a/server/Makefile +++ b/server/Makefile @@ -9,7 +9,7 @@ ETCPREFIX=/etc DISTNAME=modelbahn CXX=g++ -CXXFLAGS= -ggdb -fPIC -Wno-write-strings -g -ggdb -std=c++11 -pg +CXXFLAGS= -Wall -ggdb -fPIC -Wno-write-strings -g -ggdb -std=c++11 -pg LDFLAGS= -lm -lc -lpthread -L/usr/local/lib -g -ggdb -pg LDFLAGS_CGI= -lm -lc -lpthread -L/usr/local/lib -g -ggdb -pg diff --git a/server/interface-z21.cc b/server/interface-z21.cc index df46ac0..4e9b94a 100644 --- a/server/interface-z21.cc +++ b/server/interface-z21.cc @@ -149,8 +149,8 @@ int InterfaceZ21::Loop(string interfacename) { if (memcmp (inbuffer, RX_X_GET_TURNOUT_INFO, sizeof(RX_X_GET_TURNOUT_INFO)) == 0) { // got turnout information int addr = 0; - addr = ((unsigned char)inbuffer[Z21_IDX_SETTURNOUT_ADRH] << 8) + (unsigned char)inbuffer[Z21_IDX_SETTURNOUT_ADRL]; + debug (0, "%s:%d Interface-Z21: TurnoutInformation Addr:%d", __FILE__, __LINE__, addr); if (inbuffer[Z21_IDX_SETTURNOUT_MODE] == 2) server->TurnoutAddrMode(interfacename, addr, 1); @@ -166,12 +166,6 @@ int InterfaceZ21::Loop(string interfacename) { int cs = (unsigned char) inbuffer[16]; int csex = (unsigned char) inbuffer[17]; - bool old_poweron = status_poweron; - bool old_shortcircuit = status_shortcircuit; - bool old_programmingmode = status_programmingmode; - bool old_connected = status_connected; - bool old_emergencystop = status_emergencystop; - status_emergencystop = (cs & INTF_Z21_CS_EmergencyStop); status_poweron = (cs & INTF_Z21_CS_TrackVoltageOff); status_shortcircuit = (cs & INTF_Z21_CS_ShortCircuit); @@ -246,7 +240,7 @@ int InterfaceZ21::Loop(string interfacename) { // check for LAM_RMBUS_DATACHANGED else if (memcmp (inbuffer, RX_RMBUS_DATACHANGED, sizeof(RX_RMBUS_DATACHANGED)) == 0) { int group = (unsigned char)inbuffer[4]; - int idx, bit; + int idx; printf ("LAN_RMBUS_DATA_CHANGE[%s] ", interfacename.c_str()); for (idx = 0; idx < INTF_Z21_RMSENSOR_BYTES * INTF_Z21_RMSENSOR_GROUPS; idx++) { @@ -380,11 +374,11 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) { // // XOR Byte - for (int i = 4; i < sizeof (buffer)-1; i++) + for (int i = 4; i < (int) sizeof (buffer)-1; i++) buffer[Z21_IDX_SETLOCO_DRIVE_CHK] = (unsigned char)buffer[Z21_IDX_SETLOCO_DRIVE_CHK] xor (unsigned char)buffer[i]; printf ("Send Data:"); - for (int i = 0; i < sizeof (buffer); i++) { + for (int i = 0; i < (int)sizeof (buffer); i++) { int z = (unsigned char) buffer[i]; printf ("%02x:", z); } @@ -407,7 +401,7 @@ void InterfaceZ21::SetLocoFunction(Locomotive *l, int func, int value) { // // Set Turnout -void InterfaceZ21::SetTurnout(Turnout *t, int activate, int motoractive) { +void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) { unsigned char buffer[] = { 0x09, 0x00, 0x40, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00 }; // @@ -419,19 +413,20 @@ void InterfaceZ21::SetTurnout(Turnout *t, int activate, int motoractive) { // setup steps and selected step buffer[Z21_IDX_SETTURNOUT_MODE] = 0x80; if (activate) buffer[Z21_IDX_SETTURNOUT_MODE] |= 1; - if (motoractive) buffer[Z21_IDX_SETTURNOUT_MODE] |= 8; + if (outputactive) buffer[Z21_IDX_SETTURNOUT_MODE] |= 8; // // XOR Byte - for (int i = 4; i < sizeof (buffer)-1; i++) + for (int i = 4; i < (int) sizeof (buffer)-1; i++) buffer[Z21_IDX_SETTURNOUT_CHK] = (unsigned char)buffer[Z21_IDX_SETTURNOUT_CHK] xor (unsigned char)buffer[i]; - printf ("Send Data:"); +/* printf ("Send Data:"); for (int i = 0; i < sizeof (buffer); i++) { int z = (unsigned char) buffer[i]; printf ("%02x:", z); } printf ("\n"); +*/ udp.Write(hostname, (char*)buffer, sizeof (buffer)); }; diff --git a/server/interface-z21.h b/server/interface-z21.h index a589988..e81b996 100644 --- a/server/interface-z21.h +++ b/server/interface-z21.h @@ -74,7 +74,7 @@ class InterfaceZ21 { void PowerOnOff(int onoff); void SetLocoSpeed(Locomotive *l, int step); void SetLocoFunction(Locomotive *l, int func, int value); - void SetTurnout(Turnout *t, int activate, int motoractive); + void SetTurnout(Turnout *t, int activate, int outputactive); }; diff --git a/server/interface.cc b/server/interface.cc index 601b1a7..b9b695c 100644 --- a/server/interface.cc +++ b/server/interface.cc @@ -51,27 +51,33 @@ void Interface::PowerOnOff(int onoff) { } }; -// -// Turnout -// -void Interface::SetTurnout(Turnout *t, int active, int motoractive) { - debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetTurnout Addr:%d FinalAcitve:%d Motor:%d", name, - t->addr, active, motoractive); +/* + * Turnout: + * this function will check if the interface has not set any output within the past 100ms. For this we + * will save the current time in the value turnouttime. + */ +void Interface::SetTurnout(Turnout *t, int active, int outputactive) { + JSONParse jp; + + debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Interface (%s) SetTurnout Addr:%d Acitve:%d Output:%d", __FILE__, __LINE__, name, + t->addr, active, outputactive); - if (motoractive == 1 && timer_get(&turnouttimeout) < 100) { - debug (0, "* Interface need to wait between two turnout commands"); + // + // + if (outputactive == 1 && timer_get(&turnouttimeout) < 100) { + debug (0, "%s:%d Interface need to wait between two turnout commands", __FILE__, __LINE__); return; } timer_start(&turnouttimeout); switch (type) { - case INTF_T_Z21: intz21.SetTurnout(t, active, motoractive); break; + case INTF_T_Z21: intz21.SetTurnout(t, active, outputactive); break; default: break; } // - // make sure we turn the motor later off - if (motoractive) t->flags |= TURNOUT_F_ACTIVE; + // set the output flag + if (outputactive) t->flags |= TURNOUT_F_ACTIVE; else t->flags &= ~TURNOUT_F_ACTIVE; gettimeofday (&t->activatetime, NULL); }; @@ -328,7 +334,10 @@ void Interfaces::PowerOnOff(int onoff) { void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) { int i; + if (t == NULL) return; + 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].name[0] != 0) { if (!interfaces[i].IsConnected()) interfaces[i].Connect(); diff --git a/server/interface.h b/server/interface.h index b259310..e0aa3bb 100644 --- a/server/interface.h +++ b/server/interface.h @@ -79,7 +79,7 @@ class Interfaces { void PowerOnOff(int onoff); void SetLocoSpeed(Locomotive *l, int speed); void SetLocoFunction(Locomotive *l, int func, int value); - void SetTurnout(Turnout *t, int active, int motoractive); + void SetTurnout(Turnout *t, int active, int outputactive); void Loop(); }; diff --git a/server/json.cc b/server/json.cc index f18abc5..2ca2d6f 100644 --- a/server/json.cc +++ b/server/json.cc @@ -49,7 +49,7 @@ int JSONParse::Set(string json) { Clear(); // find start and read until end - for (step = STEP_NONE, i = 0, ignorenext = false; i < json.length(); i++) { + for (step = STEP_NONE, i = 0, ignorenext = false; i < (int) json.length(); i++) { // need to copy next character // debug (0, "JSONParse: step:%d i:%d name:'%s' value:'%s'", step, i, jelement.name.c_str(), jelement.value.c_str()); if (ignorenext) { @@ -246,7 +246,7 @@ int JSONParse::GetIdx(string src, int idx, string *dest) { // printf("\n***************************************idx:%d\n", idx); for (i = 0; i < MAXRECURSIVE; i++) recursive[i] = 0; - for (i = 0; i < src.length() && rcnt < MAXRECURSIVE && cnt <= idx; i++) { + for (i = 0; i < (int) src.length() && rcnt < MAXRECURSIVE && cnt <= idx; i++) { // printf ("i:%d rcnt:%d['%c'] cnt:%d char:'%c' ous:'%s'\n", // i, rcnt, recursive[rcnt], cnt, src[i], dest->c_str()); if (src[i] == '[') { diff --git a/server/locomotive.cc b/server/locomotive.cc index 8cf8ec5..8f76680 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -381,7 +381,6 @@ int Locomotives::GetFlags(string name) { int Locomotives::Reset(string name) { - Railway rw; int i; JSONParse jp; @@ -666,9 +665,9 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) { // int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) { int res = 0; - size_t pos1, pos2; + size_t pos1; size_t curpos; - int val, state; + int state; int newdata = 0; if (*data < 0) *data = 0; @@ -731,7 +730,7 @@ void::Locomotives::SendUpdate (Locomotive *loc) { int Locomotives::Loop() { - int lnum, i; + int lnum; string way; Locomotive *loco = NULL; string block; diff --git a/server/main.cc b/server/main.cc index 1015228..38b2d7f 100644 --- a/server/main.cc +++ b/server/main.cc @@ -20,8 +20,6 @@ Server *server = NULL; Network *network = NULL; int main (int argc, char **argv) { - int ret; - // // setup signals // diff --git a/server/modelbahn-cgi.cc b/server/modelbahn-cgi.cc index 1ab88aa..57c9117 100644 --- a/server/modelbahn-cgi.cc +++ b/server/modelbahn-cgi.cc @@ -40,7 +40,7 @@ int main (int argc, char **argv) { ptr = buffer+inlen; } if (inlen >= BUFFERSIZE-1) fprintf (logf, "read input puffer full.\n"); - fprintf (logf, "read from stdin %d bytes\n", strlen(buffer)); + fprintf (logf, "read from stdin %lud bytes\n", strlen(buffer)); // // send data to server diff --git a/server/network.cc b/server/network.cc index 87efa93..2b0063b 100644 --- a/server/network.cc +++ b/server/network.cc @@ -54,7 +54,6 @@ Network::~Network() { void Network::ThreadProcess() { list::iterator iteru; - Session *s; UNIX *u; int i = 0; @@ -181,9 +180,7 @@ Session *Network::GetSession(int sid) { int Network::ClientLoop(UNIX *client) { char bufferin[BUFFERSIZE]; - char bufferout[BUFFERSIZE]; - int len, i, rid, sid; - int res; + int len, rid, sid; list::iterator siter; Session *session = NULL; string value; @@ -232,8 +229,6 @@ int Network::ClientLoop(UNIX *client) { } if (sid <= 0) { - int x, y; - debug (0, "* sid not set, gettin new SID"); session = new Session(rid); sid = session->GetSessionID(); diff --git a/server/railway.cc b/server/railway.cc index d33aa37..1b9205e 100644 --- a/server/railway.cc +++ b/server/railway.cc @@ -222,7 +222,6 @@ JSONParse Railways::GetJSONTrack() { // change railway // return 1 on change int Railways::Change(Railway *rw) { - int x, y; int result = 1; JSONParse json; @@ -236,8 +235,6 @@ int Railways::Change(Railway *rw) { changed = true; result = 1; - if (rw->dir == 0) rw->type == RAILWAY_NOTHING; - // // need to delete? if (rw->type == RAILWAY_NOTHING) { @@ -500,7 +497,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri std::list fd_list; struct s_findway_map *fd_data = NULL; string lockedby; - int i, x ,y; + int x ,y; int found = 0; int locoflags = server->locomotives.GetFlags(lockedfor); @@ -728,8 +725,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri // // next = "b:+blockname,t:name:0,t:name:1,b:-blockname" printf ("Temp Next: %s\n", next->c_str()); - int i; - i = 0; size_t npos; if ((npos = next->find(",b:")) != string::npos) { *next = next->substr(0, next->find(",", npos+1)); @@ -760,7 +755,7 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { std::list fd_list; struct s_findway_map *fd_data = NULL; string lockedby; - int i, x ,y; + int x ,y; int found = 0; int locoflags = server->locomotives.GetFlags(lockedfor); @@ -865,7 +860,7 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { else if (rpos->type == RAILWAY_TURNOUT) { // random turn or no turn - if (rand() & 1 == 1) { + 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 @@ -965,8 +960,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { // // next = "b:+blockname,t:name:0,t:name:1,b:-blockname" debug (0, "* Random Temp Next: %s", next->c_str()); - int i; - i = 0; size_t npos; if ((npos = next->find(",b:")) != string::npos) { *next = next->substr(0, next->find(",", npos+1)); diff --git a/server/sensor.cc b/server/sensor.cc index af8c39e..a34e0cc 100644 --- a/server/sensor.cc +++ b/server/sensor.cc @@ -10,6 +10,7 @@ Sensors::Sensors () { max = SENSORS_MAX; }; + Sensors::~Sensors() { free (sensors); sensors = NULL; diff --git a/server/server-loadsave.cc b/server/server-loadsave.cc index bd402fb..9e2d28e 100644 --- a/server/server-loadsave.cc +++ b/server/server-loadsave.cc @@ -73,7 +73,7 @@ int Server::Load(string fn) { close (fd); // everything read? - if (len < sbuf.st_size) { + if (len < (size_t) sbuf.st_size) { free (buf); debug (DEBUG_ERROR, "* Reading Track File Failed. (len < filesize)"); return 0; diff --git a/server/server.cc b/server/server.cc index c8cd199..59fcb50 100644 --- a/server/server.cc +++ b/server/server.cc @@ -67,7 +67,7 @@ int Server::TurnoutSet(string name, int active) { // check if locked while (server->railways.FindReference(&x, &y, name)) { r = server->railways.Get(x, y); - printf ("Reference %d,%d Name:%s Lockedby:%d\n", x, y, r.name, r.lockedby); + // printf ("%s:%d Reference %d,%d Name:%s Lockedby:%s\n", __FILE__, __LINE__, x, y, r.name, r.lockedby); if (r.lockedby[0] != 0) { locked = 1; lockedby = r.lockedby; @@ -251,7 +251,7 @@ void Server::CycleModeReset() { else { data_reset.mr_idx = -1; data_reset.mr_step++; - data_reset.mr_lastelm; + data_reset.mr_lastelm = ""; } } } @@ -264,19 +264,23 @@ void Server::CycleModeReset() { data_reset.mr_idx++; data_reset.mr_lastelm = turnouts.GetName(data_reset.mr_idx); - flags = turnouts.GetFlags(data_reset.mr_idx); - if (flags & TURNOUT_F_TURNOUT) active = 1; - else active = 0; - timer_start (&data_reset.mr_timestamp); - if (data_reset.mr_lastelm.length() > 0) { - debug (0, "* Reset Turnout %s", data_reset.mr_lastelm.c_str()); - TurnoutSet(data_reset.mr_lastelm, active); + // + // reset output/turnout only if not a relais + flags = turnouts.GetFlags(data_reset.mr_idx); + if ((flags & TURNOUT_F_ISRELAIS) == 0) { + if (flags & TURNOUT_F_TURNOUT) active = 1; + else active = 0; + timer_start (&data_reset.mr_timestamp); + + debug (0, "* Reset Turnout %s", data_reset.mr_lastelm.c_str()); + TurnoutSet(data_reset.mr_lastelm, active); + } } else { data_reset.mr_idx = -1; data_reset.mr_step++; - data_reset.mr_lastelm; + data_reset.mr_lastelm = ""; } } } diff --git a/server/session.cc b/server/session.cc index 4a3d75c..95f5097 100644 --- a/server/session.cc +++ b/server/session.cc @@ -675,9 +675,6 @@ void Session::SetJSONTurnout(JSONParse *jp) { string name; string lockedby; int active; - int x, y; - int locked = 0; - Railway r; server->LockThread(); @@ -689,9 +686,6 @@ void Session::SetJSONTurnout(JSONParse *jp) { // activate debug (0, "%s:%d SetJSONTurnout Element %s active:%d", __FILE__, __LINE__, name.c_str(), active); server->TurnoutSet(name, active); - jout.Clear(); - jout.AddObject("turnout", server->TurnoutGetJSON(name)); - if (network) network->ChangeListPushToAll(jout.ToString()); } server->UnLockThread(); }; diff --git a/server/turnout.cc b/server/turnout.cc index a640f65..d29b26b 100644 --- a/server/turnout.cc +++ b/server/turnout.cc @@ -164,20 +164,33 @@ int Turnouts::Delete(string name) { int Turnouts::Set(string name, int value) { int i; + JSONParse jp; // Lock(); for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) { if (name.compare(turnouts[i].name) == 0) { - debug (0, "Turnout::Set: Name:%s Flags:%d[%c%c%c] Value:%d", name.c_str(), turnouts[i].flags, - (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-', - (turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-', + debug (0, "%s:%d Turnout::Set: Name:%s Flags:%d[%c%c%c%c] Value:%d", __FILE__, __LINE__, name.c_str(), turnouts[i].flags, + (turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-', (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-', + (turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-', + (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-', value); - if (turnouts[i].flags & TURNOUT_F_INVERSE) - server->interfaces.SetTurnout(&turnouts[i], !value, 1); // motor on - else - server->interfaces.SetTurnout(&turnouts[i], value, 1); // motor on + if (turnouts[i].flags & TURNOUT_F_ISRELAIS) { + printf ("%s:%d is relais.... %d\n", __FILE__, __LINE__, value); + server->interfaces.SetTurnout(&turnouts[i], value, value); + } + else { + if (turnouts[i].flags & TURNOUT_F_INVERSE) + server->interfaces.SetTurnout(&turnouts[i], !value, 1); // motor on + else + server->interfaces.SetTurnout(&turnouts[i], value, 1); // motor on + } + + jp.Clear(); + jp.AddObject("turnout", _GetJSON(i)); + if (network) network->ChangeListPushToAll(jp.ToString()); + gettimeofday (&turnouts[i].activatetime, NULL); changed = 1; @@ -215,14 +228,15 @@ void Turnouts::SetFromBus(string ifname, int addr, int value) { int i; JSONParse jp; - debug (0, "Turnouts::SetFromBus Interface:%s, addr: %d, value:%d", ifname.c_str(), addr, value); + debug (0, "%s:%d Turnouts::SetFromBus Interface:%s, addr: %d, value:%d", __FILE__, __LINE__, ifname.c_str(), addr, value); for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) { if (ifname.compare(turnouts[i].ifname) == 0 && turnouts[i].addr == addr) { - debug (0, "Turnout::SetFromBus Name:%s Flags:%d[%c%c%c]", turnouts[i].name, turnouts[i].flags, - (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-', + debug (0, "%s:%d Turnout::SetFromBus Name:%s Flags:%d[%c%c%c%c]", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags, + (turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-', + (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-', (turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-', - (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-'); + (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-'); // if (value) turnouts[i].flags |= TURNOUT_F_ACTIVE; // else turnouts[i].flags &= ~TURNOUT_F_ACTIVE; @@ -235,10 +249,11 @@ void Turnouts::SetFromBus(string ifname, int addr, int value) { if (value) turnouts[i].flags |= TURNOUT_F_TURNOUT; else turnouts[i].flags &= ~TURNOUT_F_TURNOUT; } - debug (0, "Turnout::SetFromBus Name:%s Flags:%d[%c%c%c]", turnouts[i].name, turnouts[i].flags, - (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-', + debug (0, "%s:%d Turnout::SetFromBus Name:%s Flags:%d[%c%c%c%c]", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags, + (turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-', + (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-', (turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-', - (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-'); + (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-'); jp.AddObject("turnout", _GetJSON(i)); if(network) network->ChangeListPushToAll(jp.ToString()); @@ -248,11 +263,13 @@ void Turnouts::SetFromBus(string ifname, int addr, int value) { -// -// this loop is important: Turnout motors needs to be deactivated after a short time -// +/* + * this loop is important: some outputs especially motors needs to be deactivated + * after a short period of time. + */ void Turnouts::Loop() { int i; + JSONParse jp; struct timeval curtime; gettimeofday(&curtime, NULL); @@ -260,9 +277,9 @@ void Turnouts::Loop() { Lock(); for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) { - if (turnouts[i].flags & TURNOUT_F_ACTIVE) { + if ((turnouts[i].flags & TURNOUT_F_ACTIVE) && ((turnouts[i].flags & TURNOUT_F_ISRELAIS) == 0)) { // - // motor still active check timeout and deactivate + // motor/output still active check timeout and deactivate int timediff = (1000 * (curtime.tv_sec - turnouts[i].activatetime.tv_sec)) + ((curtime.tv_usec - turnouts[i].activatetime.tv_usec) / 1000); if (timediff < 0) gettimeofday (&turnouts[i].activatetime, NULL); @@ -270,12 +287,25 @@ void Turnouts::Loop() { // debug (0, "%s:%d timediff: %d", __FILE__, __LINE__, timediff); if (timediff > turnouts[i].activetimeout) { - int active = turnouts[i].flags & TURNOUT_F_TURNOUT; + int turnout = (turnouts[i].flags & TURNOUT_F_TURNOUT) != 0 ? 1 : 0; + + debug (0, "%s:%d Turnout::Loop Name:%s Flags:%d[%c%c%c%c] Turnout:%d", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags, + (turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-', + (turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-', + (turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-', + (turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-', + turnout); + if (turnouts[i].flags & TURNOUT_F_INVERSE) - server->interfaces.SetTurnout(&turnouts[i], !active, 0); // motor on + server->interfaces.SetTurnout(&turnouts[i], !turnout, 0); // motor on else - server->interfaces.SetTurnout(&turnouts[i], active, 0); // motor on + server->interfaces.SetTurnout(&turnouts[i], turnout, 0); // motor on + turnouts[i].flags &= ~TURNOUT_F_ACTIVE; + + jp.Clear(); + jp.AddObject("turnout", _GetJSON(i)); + if (network) network->ChangeListPushToAll(jp.ToString()); } } } diff --git a/server/turnout.h b/server/turnout.h index e09404b..c4f2a04 100644 --- a/server/turnout.h +++ b/server/turnout.h @@ -5,9 +5,10 @@ #include "modelbahn.h" #include "server.h" // -#define TURNOUT_F_INVERSE 0x0001 // inverse output -#define TURNOUT_F_ACTIVE 0x0002 // motor active -#define TURNOUT_F_TURNOUT 0x0004 // turnout active +#define TURNOUT_F_INVERSE 0x0001 // inverse output +#define TURNOUT_F_ACTIVE 0x0002 // motor/output active +#define TURNOUT_F_TURNOUT 0x0004 // turnout active +#define TURNOUT_F_ISRELAIS 0x0008 // output is relais no auto off #define TURNOUT_DEFAULT_ACTIVETIMEOUT 250 // active timeout default value diff --git a/webinterface/layout.css b/webinterface/layout.css index c7da369..e8c1416 100644 --- a/webinterface/layout.css +++ b/webinterface/layout.css @@ -33,6 +33,8 @@ body { --turnout-other: #666; --sensor-active: #0F0; --sensor-inactive: #666; + --button-active: #0F0; + --button-inactive: #666; } .page_side { diff --git a/webinterface/railways.js b/webinterface/railways.js index e4dbe13..5620756 100644 --- a/webinterface/railways.js +++ b/webinterface/railways.js @@ -2,9 +2,21 @@ // // +const RAILWAY_T_NOTHING = 0; +const RAILWAY_T_NORMAL = 1; +const RAILWAY_T_CROSSING = 2; +const RAILWAY_T_TURNOUT = 3; +const RAILWAY_T_SENSOR = 4; +const RAILWAY_T_CONNECTOR = 5; +const RAILWAY_T_BUTTON = 6; +const RAILWAY_T_TEXT = 7; +const RAILWAY_T_BLOCK = 8; + + const TURNOUT_F_INVERSE = 1; -const TURNOUT_F_MOTORACTIVE = 2; +const TURNOUT_F_OUTPUTACTIVE = 2; const TURNOUT_F_TURNOUT = 4; +const TURNOUT_F_ISRELAIS = 8; function rwdetail_requestcallback(response) { @@ -103,10 +115,10 @@ function rwdetail_cb_gotoref () { debug ("Name:" + name.value + " Type:" + type.value); switch(Number(type.value)) { - case 3: turndetail_show(name.value, true); break; // turnout - case 4: sensordetail_show(name.value, true); break; // sensor - case 5: break; // connector - case 8: blockdetail_show(name.value, true); break; // block + case RAILWAY_T_BUTTON: turndetail_show(name.value, true); break; // button + case RAILWAY_T_TURNOUT: turndetail_show(name.value, true); break; // turnout + case RAILWAY_T_SENSOR: sensordetail_show(name.value, true); break; // sensor + case RAILWAY_T_BLOCK: blockdetail_show(name.value, true); break; // block default: break; } }; @@ -218,10 +230,23 @@ function rw_Click(x,y) { var idx = x + y * track.size.x; if (track.elements[idx]) { // - // Button or Turnout? - if (track.elements[idx].type == RAILWAY_TURNOUT || track.elements[idx].type == RAILWAY_BUTTON) { + // Turnout? + if (track.elements[idx].type == RAILWAY_TURNOUT) { + if (track.elements[idx].name != "") { + if (turnout_IsTurnoutActive(track.elements[idx].name)) { + turnout_server_Activate(track.elements[idx].name, 0); + } + else { + turnout_server_Activate(track.elements[idx].name, 1); + } + } + } + + // + // Button + else if (track.elements[idx].type == RAILWAY_T_BUTTON) { if (track.elements[idx].name != "") { - if (turnout_IsActive(track.elements[idx].name)) { + if (turnout_IsOutputActive(track.elements[idx].name)) { turnout_server_Activate(track.elements[idx].name, 0); } else { @@ -284,7 +309,7 @@ var turnouts = []; function turnout_Update(data) { for (var i = 0; i < turnouts.length; i++) { if (data.name == turnouts[i].name) { - debug ("Update turnout:" + turnouts[i].name + " with turnout:" + data.name); + debug ("Update turnout:" + turnouts[i].name + " with turnout:" + data.name + " Flags:" + data.flags); turnouts[i].name = data.name; turnouts[i].ifname = data.ifname; turnouts[i].addr = data.addr; @@ -294,7 +319,7 @@ function turnout_Update(data) { } // not found add element - debug ("Add turnout:" + data.name); + debug ("Add turnout:" + data.name + " Flags:" + data.flags); turnouts.push ({ name: data.name, ifname: data.ifname, @@ -307,7 +332,7 @@ function turnout_Update(data) { // // return if the turnout is active or not // -function turnout_IsActive(name) { +function turnout_IsTurnoutActive(name) { for (var i = 0; i < turnouts.length; i++) { if (name == turnouts[i].name) { if (turnouts[i].flags & TURNOUT_F_TURNOUT) return 1 @@ -318,6 +343,17 @@ function turnout_IsActive(name) { }; +function turnout_IsOutputActive(name) { + for (var i = 0; i < turnouts.length; i++) { + if (name == turnouts[i].name) { + if (turnouts[i].flags & TURNOUT_F_OUTPUTACTIVE) return 1 + else return 0; + } + } + return 0; +} + + // // delete element from the list // in arrays we can not delete just an element, so we create a new one @@ -385,6 +421,8 @@ function turndetail_show(turnname, create) { Flags: \ \
\ +
\ +
\ \ \
\ @@ -398,6 +436,8 @@ function turndetail_show(turnname, create) { gAddEventListener("turndet_inverse", 'click', turndetail_cb_inverse); gAddEventListener("turndet_active", 'click', turndetail_cb_active); + gAddEventListener("turndet_output", 'click', turndetail_cb_output); + gAddEventListener("turndet_relais", 'click', turndetail_cb_relais); gAddEventListener("turndet_CLOSE", 'click', turndetail_cb_close); gAddEventListener("turndet_DELETE", 'click', turndetail_cb_delete); @@ -457,6 +497,34 @@ function turndetail_cb_active () { }; +// +// output +function turndetail_cb_output () { + var cb = document.getElementById("turndet_output"); + var flags = document.getElementById("turndet_flags"); + var name = document.getElementById("turndet_name"); + + if (cb.checked) + flags.value = Number(flags.value) | TURNOUT_F_OUTPUTACTIVE; + else + flags.value = Number(flags.value) & (0xFFFF-TURNOUT_F_OUTPUTACTIVE); +}; + + +// +// isrelais +function turndetail_cb_relais () { + var cb = document.getElementById("turndet_relais"); + var flags = document.getElementById("turndet_flags"); + var name = document.getElementById("turndet_name"); + + if (cb.checked) + flags.value = Number(flags.value) | TURNOUT_F_ISRELAIS; + else + flags.value = Number(flags.value) & (0xFFFF-TURNOUT_F_ISRELAIS); +}; + + function turndetail_cb_close () { var win = document.getElementById("turndetail"); @@ -544,6 +612,8 @@ function turndetail_setData(elm) { var turnflags = document.getElementById("turndet_flags"); var cbinverse = document.getElementById("turndet_inverse"); var cbactive = document.getElementById("turndet_active"); + var cbrelais = document.getElementById("turndet_relais"); + var cboutput = document.getElementById("turndet_output"); if (elm) { if (turnname) turnname.value = elm.name; @@ -551,13 +621,21 @@ function turndetail_setData(elm) { if (turnaddr) turnaddr.value = elm.addr; if (turnflags) turnflags.value = elm.flags; if (cbinverse) { - if (Number(elm.flags) & 1) cbinverse.checked = true; + if (Number(elm.flags) & TURNOUT_F_INVERSE) cbinverse.checked = true; else cbinverse.checked = false; } if (cbactive) { - if (Number(elm.flags) & 2) cbactive.checked = true; + if (Number(elm.flags) & TURNOUT_F_TURNOUT) cbactive.checked = true; else cbactive.checked = false; } + if (cboutput) { + if (Number(elm.flags) & TURNOUT_F_OUTPUTACTIVE) cboutput.checked = true; + else cboutput.checked = false; + } + if (cbrelais) { + if (Number(elm.flags) & TURNOUT_F_ISRELAIS) cbrelais.checked = true; + else cbrelais.checked = false; + } } }; diff --git a/webinterface/track.js b/webinterface/track.js index a5c3fa6..043815c 100644 --- a/webinterface/track.js +++ b/webinterface/track.js @@ -119,7 +119,7 @@ function trackDrawElement(ctx, element, mode) { var dir = element.dir; var altdir = element.altdir; - if (element.name != "") if (turnout_IsActive(element.name)) { + if (element.name != "") if (turnout_IsTurnoutActive(element.name)) { // debug ("draw element:" + element.name + " isActive:" + turnout_IsActive(element.name)); altdir = element.dir; dir = element.altdir; @@ -137,6 +137,26 @@ function trackDrawElement(ctx, element, mode) { trackDrawTrack (ctx, {x: element.x, y: element.y}, altdir); } + else if (element.type == RAILWAY_BUTTON) { + let bi; + ctx.beginPath(); + ctx.lineWidth = 2; + ctx.setLineDash([0,0]); + + ctx.strokeStyle = cssVar('--button-inactive'); + for (bi = 0; bi < turnouts.length; bi++) { + if (turnouts[bi].name == element.name) { + if ((turnouts[bi].flags & TURNOUT_F_OUTPUTACTIVE) != 0) + ctx.strokeStyle = cssVar('--button-active'); + } + } + ctx.moveTo((element.x+0.1) * track.scale, (element.y+0.1) * track.scale); + ctx.lineTo((element.x+0.9) * track.scale, (element.y+0.1) * track.scale); + ctx.lineTo((element.x+0.9) * track.scale, (element.y+0.9) * track.scale); + ctx.lineTo((element.x+0.1) * track.scale, (element.y+0.9) * track.scale); + ctx.lineTo((element.x+0.1) * track.scale, (element.y+0.1) * track.scale); + ctx.stroke(); + } else if (element.type == RAILWAY_NORMAL || element.type == RAILWAY_SENSOR || element.type == RAILWAY_BLOCK) { // // normal