Is anyone here interested in Train Signals and how they work?

I'm messing around with train block signals.

How tracks are controlled.

How trains go along them.

And all that sort of stuff.

Just asking.

Maybe it's me... but from your posting it's not clear... whether you are asking for information/help or offering to give it?

Also is this for model trains or a real railway network (and if so, in what country?).

Happy New Year

It is just the mechanics of them and the signalling.

It has me interested.

This is a basic flow.
The "train" runs right to left. Signals only.

For Oz.
I haven't got ALL the signals, but most of the mostly used ones. in the Sydney area.
It isn't prefect on how it displays the signals/lights, but that is a simple GUI change/addition.

Press the START button to start things happening. There is a 5 second pause.

EXTRA NODES NEEDED!
node-red-contrib-fan
node-red-contrib-simple-gate

ARGH!
Body is limited to 32000 characters; you entered 32655.

Subflow needed:

[{"id":"4a1b3556.f7d3bc","type":"subflow","name":"Block Control 2","info":"","category":"","in":[{"x":260,"y":720,"wires":[{"id":"1523fda4.8aad7a"}]}],"out":[{"x":3460,"y":350,"wires":[{"id":"b9a05a95.d8db7","port":0}]},{"x":3460,"y":410,"wires":[{"id":"16d223b2.e56154","port":0}]},{"x":3460,"y":470,"wires":[{"id":"dc0e45f1.32ca28","port":0}]},{"x":3460,"y":530,"wires":[{"id":"ad4bdcf4.4f4df8","port":0}]},{"x":3460,"y":780,"wires":[{"id":"daf57362.31533","port":0}]},{"x":3460,"y":880,"wires":[{"id":"fed63556.3f50f","port":0}]},{"x":3470,"y":1130,"wires":[{"id":"3c3d37fc.7fffa8","port":0}]}],"env":[],"color":"#DDAA99","inputLabels":["Upstream Block status"],"outputLabels":["Downstream Block status","Top Light","Bottom Light","Small light","Point status","Point Icon symbol","Train message output"]},{"id":"19054125.1f91ef","type":"comment","z":"4a1b3556.f7d3bc","name":"Modes and colours","info":"Clear   Green Green\nMedium  Green Yellow\nCaution Green Red\nLow Speed  Red Red Green\nStop    Red Red\nTurnout Yellow Yellow\nTurnoutCaution   Yellow Red","x":710,"y":70,"wires":[]},{"id":"6fccf0c7.8c1c38","type":"comment","z":"4a1b3556.f7d3bc","name":"Control Input","info":"","x":510,"y":370,"wires":[]},{"id":"e1a820f.7da51e","type":"fan","z":"4a1b3556.f7d3bc","x":640,"y":440,"wires":[["9d9f3f27.f36918","91d7c3ef.946ce"]]},{"id":"fbc753eb.75675","type":"fan","z":"4a1b3556.f7d3bc","x":690,"y":1130,"wires":[["d2f5757c.e19948"]]},{"id":"e32d1c65.c29448","type":"inject","z":"4a1b3556.f7d3bc","name":"Turn","topic":"CONTROL","payload":"TURN","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":490,"y":440,"wires":[["e1a820f.7da51e"]]},{"id":"dd179fab.d903b8","type":"inject","z":"4a1b3556.f7d3bc","name":"Ahead","topic":"CONTROL","payload":"AHEAD","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":490,"y":410,"wires":[["e1a820f.7da51e"]]},{"id":"bf2b729b.8c674","type":"inject","z":"4a1b3556.f7d3bc","name":"Hold","topic":"CONTROL","payload":"HOLD","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":490,"y":470,"wires":[["e1a820f.7da51e"]]},{"id":"882384dd.1ea9","type":"inject","z":"4a1b3556.f7d3bc","name":"Release","topic":"CONTROL","payload":"RELEASE","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":500,"y":500,"wires":[["e1a820f.7da51e"]]},{"id":"8eb9f9fc.6d11e8","type":"comment","z":"4a1b3556.f7d3bc","name":"Train Input","info":"","x":510,"y":1030,"wires":[]},{"id":"9d9f3f27.f36918","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"AHEAD","vt":"str"},{"t":"eq","v":"TURN","vt":"str"},{"t":"eq","v":"HOLD","vt":"str"},{"t":"eq","v":"RELEASE","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":770,"y":440,"wires":[["29e19a1d.59268e"],["1a7cf04f.f81b6"],["98dd15ba.a5994"],["834dc938.15f328"]]},{"id":"1a7cf04f.f81b6","type":"change","z":"4a1b3556.f7d3bc","name":"Turn","rules":[{"t":"set","p":"POINT","pt":"flow","to":"TURN","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":430,"wires":[["622e31f7.a9781"]]},{"id":"29e19a1d.59268e","type":"change","z":"4a1b3556.f7d3bc","name":"Ahead","rules":[{"t":"set","p":"POINT","pt":"flow","to":"AHEAD","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":400,"wires":[["622e31f7.a9781"]]},{"id":"b78cc8e8.8bfa8","type":"fan","z":"4a1b3556.f7d3bc","x":1090,"y":730,"wires":[["3591720.73f210e","ee4af5a8.931b08"]]},{"id":"3591720.73f210e","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"AHEAD","vt":"str"},{"t":"eq","v":"POINTS","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1220,"y":730,"wires":[["d0a6aab5.38573"],["665b1156.498698"]]},{"id":"d0a6aab5.38573","type":"change","z":"4a1b3556.f7d3bc","name":"Ahead condition","rules":[{"t":"set","p":"AHEAD","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1410,"y":690,"wires":[[]]},{"id":"1cee5859.1c11","type":"change","z":"4a1b3556.f7d3bc","name":"Turn condition","rules":[{"t":"set","p":"TURN","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1490,"y":780,"wires":[[]]},{"id":"b3b280e2.645798","type":"fan","z":"4a1b3556.f7d3bc","x":1060,"y":460,"wires":[["d65eb24.dd192d"]]},{"id":"8416356f.800818","type":"comment","z":"4a1b3556.f7d3bc","name":"Signal","info":"","x":1060,"y":370,"wires":[]},{"id":"665b1156.498698","type":"function","z":"4a1b3556.f7d3bc","name":"Point message modification","func":"if (msg.topic == \"POINTS\")\n{\n    if (flow.get('DEBUG') == 1)\n    {\n        node.warn(\"POINT MESSAGE RECEIVED\");\n        node.warn(\"Payload = \" + msg.payload);\n    }\n    //  Messages have to be changed\n    if (msg.payload == \"CLEAR\")\n    {\n        msg.payload = \"TURNOUT\";\n//        return msg;\n    } else\n    if (msg.payload == \"MEDIUM\")\n    {\n        msg.payload = \"TURNOUT\";\n    } else\n    if (msg.payload == \"CAUTION\")\n    {\n        msg.payload = \"TURNOUTCAUTION\";\n//        return msg;\n    } else\n    if (msg.payload == \"STOP\")\n    {\n        msg.payload = \"LOWSPEED\";\n    } else\n    if (msg.payload == \"HOLD\")\n    {\n        msg.payload = \"TURNOUTCAUTION\";\n    } else\n    if (msg.payload == \"LOWSPEED\")\n    {\n        msg.payload = \"TURNOUTCAUTION\";\n        node.warn(\"*******  TURN OUT CAUTION ***********\");\n    }\n}\nif (flow.get('DEBUG') == 1)\n{\n    node.warn(\"NEW POINT MESSAGE\");\n    node.warn(\"Payload = \" + msg.payload);\n}\n\nreturn msg;\n","outputs":1,"noerr":0,"x":1450,"y":740,"wires":[["1cee5859.1c11"]]},{"id":"794907b4.8b442","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"CONTROL","vt":"str"},{"t":"eq","v":"TRAIN","vt":"str"},{"t":"eq","v":"DEBUG","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":740,"y":720,"wires":[["50cb4ee1.f7663"],["a05cf778.1e42c"],["cb87fd5.635f"],["b78cc8e8.8bfa8"]]},{"id":"77895fc5.b0174","type":"inject","z":"4a1b3556.f7d3bc","name":"Trip","topic":"TRAIN","payload":"TRIP","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":520,"y":1130,"wires":[["fbc753eb.75675"]]},{"id":"1523fda4.8aad7a","type":"fan","z":"4a1b3556.f7d3bc","x":510,"y":720,"wires":[["794907b4.8b442","42712278.b4cc44"]]},{"id":"834dc938.15f328","type":"function","z":"4a1b3556.f7d3bc","name":"Release","func":"let x = flow.get('POINT') || 0;    //  AHEAD/TURN\nvar p;\n//node.warn(\"X \" + x)\n\nflow.set('MODE','RELEASE');\n\nif (x == 'AHEAD')\n{\n//    node.warn(\">>  AHEAD\");\n    p = flow.get('AHEAD');\n//    node.warn(\"Payload \" + p);\n    msg = {'payload':p, 'topic':'AHEAD'};\n} else\nif (x == 'TURN')\n{\n//    node.warn(\">>  TURN\");\n    p = flow.get('TURN');\n//    node.warn(\"Payload \" + p);\n    msg = {'payload':p, 'topic': 'POINTS'};\n}\nreturn msg;","outputs":1,"noerr":0,"x":910,"y":490,"wires":[["cdab01c7.08a0b8","eedbc890.a306d","6f453bf2.302274"]]},{"id":"9aaa983e.ac8758","type":"debug","z":"4a1b3556.f7d3bc","name":"Input","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":940,"y":620,"wires":[]},{"id":"8d67546e.0165f8","type":"fan","z":"4a1b3556.f7d3bc","x":2000,"y":490,"wires":[["29f6c9bf.9eb586","6e7e9e36.7c279","c82fba31.8ea91"]]},{"id":"13541e80.3dc8aa","type":"debug","z":"4a1b3556.f7d3bc","name":"(Output) Local","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":2050,"y":540,"wires":[]},{"id":"3d894ea3.c8cab2","type":"gate","z":"4a1b3556.f7d3bc","name":"","controlTopic":"CONTROL","defaultState":"closed","openCmd":"TURN","closeCmd":"AHEAD","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":1610,"y":880,"wires":[["47f0add1.05be4c"]]},{"id":"6bcb3259.53cb64","type":"debug","z":"4a1b3556.f7d3bc","name":"Control signal","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":890,"y":320,"wires":[]},{"id":"ff917300.690668","type":"gate","z":"4a1b3556.f7d3bc","name":"","controlTopic":"CONTROL","defaultState":"closed","openCmd":"AHEAD","closeCmd":"TURN","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":1610,"y":830,"wires":[["5929662b.c3d49"]]},{"id":"622e31f7.a9781","type":"fan","z":"4a1b3556.f7d3bc","x":1060,"y":410,"wires":[["174b78ee.38f28f"]]},{"id":"e9be75b2.b13c78","type":"function","z":"4a1b3556.f7d3bc","name":"pulse","func":"msg = {'payload':\"blah\",'topic':null};\nreturn msg;","outputs":1,"noerr":0,"x":1440,"y":830,"wires":[["ff917300.690668","3d894ea3.c8cab2","af6a5d3b.8c8cc8"]]},{"id":"5929662b.c3d49","type":"change","z":"4a1b3556.f7d3bc","name":"Ahead","rules":[{"t":"set","p":"payload","pt":"msg","to":"AHEAD","tot":"flow"},{"t":"set","p":"topic","pt":"msg","to":"AHEAD","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1740,"y":830,"wires":[["cca98bfa.d23"]]},{"id":"47f0add1.05be4c","type":"change","z":"4a1b3556.f7d3bc","name":"Point","rules":[{"t":"set","p":"payload","pt":"msg","to":"TURN","tot":"flow"},{"t":"set","p":"topic","pt":"msg","to":"POINTS","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1740,"y":880,"wires":[["cca98bfa.d23"]]},{"id":"ee4af5a8.931b08","type":"delay","z":"4a1b3556.f7d3bc","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1230,"y":770,"wires":[["b76c3a13.5063e8"]]},{"id":"c1cba23.82beae","type":"link in","z":"4a1b3556.f7d3bc","name":"CONTROL","links":["50cb4ee1.f7663"],"x":500,"y":530,"wires":[["e1a820f.7da51e"]],"l":true},{"id":"50cb4ee1.f7663","type":"link out","z":"4a1b3556.f7d3bc","name":"CONTROL","links":["c1cba23.82beae"],"x":890,"y":660,"wires":[],"l":true},{"id":"174b78ee.38f28f","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["535eb5e6.359dfc","2ebbf4c6.3e7cbc"],"x":1150,"y":410,"wires":[]},{"id":"535eb5e6.359dfc","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["174b78ee.38f28f"],"x":1475,"y":880,"wires":[["ff917300.690668","3d894ea3.c8cab2","af6a5d3b.8c8cc8"]]},{"id":"cdab01c7.08a0b8","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["a297e51f.ac21b8","fd93dcfa.adf11","7608c171.2052f","ad1d8c1d.583c4","b782e7f.ea27698"],"x":1185,"y":490,"wires":[]},{"id":"6afc817a.60b268","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["cca98bfa.d23","8cb43c35.89c2c","35523cd9.5bcb1c","d9a66601.c20068","4b13a510.2aea9c","24ce82bc.06e076","d65eb24.dd192d"],"x":1905,"y":490,"wires":[["8d67546e.0165f8"]]},{"id":"a05cf778.1e42c","type":"link out","z":"4a1b3556.f7d3bc","name":"TRAIN","links":["74ba4b0c.e865dc"],"x":880,"y":690,"wires":[],"l":true},{"id":"74ba4b0c.e865dc","type":"link in","z":"4a1b3556.f7d3bc","name":"TRAIN","links":["a05cf778.1e42c"],"x":520,"y":1080,"wires":[["fbc753eb.75675"]],"l":true},{"id":"2ebbf4c6.3e7cbc","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["174b78ee.38f28f"],"x":1105,"y":620,"wires":[["b78cc8e8.8bfa8"]]},{"id":"36e92efe.18e04a","type":"function","z":"4a1b3556.f7d3bc","name":"Clear","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"CLEAR\";\nmsg1 = {payload:\"Green\"};\nmsg2 = {payload:\"Green\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2460,"y":230,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"29f6c9bf.9eb586","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"CLEAR","vt":"str"},{"t":"eq","v":"MEDIUM","vt":"str"},{"t":"eq","v":"CAUTION","vt":"str"},{"t":"eq","v":"LOWSPEED","vt":"str"},{"t":"eq","v":"STOP","vt":"str"},{"t":"eq","v":"TURNOUT","vt":"str"},{"t":"eq","v":"TURNOUTCAUTION","vt":"str"},{"t":"eq","v":"HOLD","vt":"str"}],"checkall":"true","repair":false,"outputs":8,"x":2250,"y":490,"wires":[["36e92efe.18e04a"],["7754ee07.dbc23"],["2c3e6a0d.e91a56"],["bb2fb24b.f8b418"],["9332c0ea.c6dd8"],["78a5ccfb.2adb2c"],["58832734.45d468"],["585f3ce8.646fac"]]},{"id":"7754ee07.dbc23","type":"function","z":"4a1b3556.f7d3bc","name":"Medium","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"CLEAR\";\nmsg1 = {payload:\"Green\"};\nmsg2 = {payload:\"Yellow\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2470,"y":300,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"2c3e6a0d.e91a56","type":"function","z":"4a1b3556.f7d3bc","name":"Caution","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"MEDIUM\";\nmsg1 = {payload:\"Green\"};\nmsg2 = {payload:\"Red\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2470,"y":370,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"bb2fb24b.f8b418","type":"function","z":"4a1b3556.f7d3bc","name":"LowSpeed","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"CAUTION\";\nmsg1 = {payload:\"Red\"};\nmsg2 = {payload:\"Red\"};\nmsg3 = {payload:\"Green\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2480,"y":440,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"9332c0ea.c6dd8","type":"function","z":"4a1b3556.f7d3bc","name":"Stop","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"LOWSPEED\";\nmsg1 = {payload:\"Red\"};\nmsg2 = {payload:\"Red\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2460,"y":510,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"78a5ccfb.2adb2c","type":"function","z":"4a1b3556.f7d3bc","name":"Turnout","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"MEDIUM\";\nmsg1 = {payload:\"Yellow\"};\nmsg2 = {payload:\"Yellow\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2470,"y":580,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"58832734.45d468","type":"function","z":"4a1b3556.f7d3bc","name":"TurnoutCaution","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"MEDIUM\";\nmsg1 = {payload:\"Yellow\"};\nmsg2 = {payload:\"Red\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2490,"y":650,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"585f3ce8.646fac","type":"function","z":"4a1b3556.f7d3bc","name":"Hold","func":"msg1 = {};\nmsg2 = {};\nmsg3 = {};\nmsg.payload = \"LOWSPEED\";\nmsg1 = {payload:\"Red\"};\nmsg2 = {payload:\"Red\"};\nmsg3 = {payload:\"Black\"};\nreturn [msg,msg1,msg2,msg3];","outputs":4,"noerr":0,"x":2460,"y":720,"wires":[["179c0166.174eef"],["3a196841.25c3a"],["dbde5807.387f48"],["c1774a16.3617c"]]},{"id":"179c0166.174eef","type":"fan","z":"4a1b3556.f7d3bc","x":2740,"y":350,"wires":[["b9a05a95.d8db7"]]},{"id":"3a196841.25c3a","type":"fan","z":"4a1b3556.f7d3bc","x":2740,"y":410,"wires":[["16d223b2.e56154"]]},{"id":"dbde5807.387f48","type":"fan","z":"4a1b3556.f7d3bc","x":2740,"y":470,"wires":[["dc0e45f1.32ca28"]]},{"id":"c1774a16.3617c","type":"fan","z":"4a1b3556.f7d3bc","x":2740,"y":530,"wires":[["ad4bdcf4.4f4df8"]]},{"id":"ea53d690.43e628","type":"comment","z":"4a1b3556.f7d3bc","name":"Output to previous signal block","info":"","x":2930,"y":310,"wires":[]},{"id":"33c1dee5.d439aa","type":"comment","z":"4a1b3556.f7d3bc","name":"Top Light","info":"","x":2860,"y":380,"wires":[]},{"id":"80d9dd7f.c3b5d8","type":"comment","z":"4a1b3556.f7d3bc","name":"Bottom Light","info":"","x":2870,"y":440,"wires":[]},{"id":"d8a2f14b.0d11c","type":"comment","z":"4a1b3556.f7d3bc","name":"Small Light","info":"","x":2860,"y":500,"wires":[]},{"id":"16d223b2.e56154","type":"change","z":"4a1b3556.f7d3bc","name":"Top","rules":[{"t":"set","p":"colour.A","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2860,"y":410,"wires":[["b17a207d.6b7bb"]]},{"id":"dc0e45f1.32ca28","type":"change","z":"4a1b3556.f7d3bc","name":"Bottom","rules":[{"t":"set","p":"colour.B","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2870,"y":470,"wires":[["4bc8dec8.446f38"]]},{"id":"ad4bdcf4.4f4df8","type":"change","z":"4a1b3556.f7d3bc","name":"SMall","rules":[{"t":"set","p":"colour.C","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2860,"y":530,"wires":[["f2e4ddaf.afdb68"]]},{"id":"b9a05a95.d8db7","type":"change","z":"4a1b3556.f7d3bc","name":"Straight","rules":[{"t":"set","p":"topic","pt":"msg","to":"AHEAD","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2870,"y":350,"wires":[["802d089d.d3de28"]]},{"id":"a0bfd49c.441088","type":"change","z":"4a1b3556.f7d3bc","name":"Point","rules":[{"t":"set","p":"payload","pt":"msg","to":"POINT","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":2460,"y":780,"wires":[["733fd106.a20d88","e3ff941b.44d108"]]},{"id":"19f4ce3e.54c112","type":"fan","z":"4a1b3556.f7d3bc","x":2760,"y":780,"wires":[["daf57362.31533"]]},{"id":"b530d00a.022b78","type":"comment","z":"4a1b3556.f7d3bc","name":"Input","info":"","x":510,"y":640,"wires":[]},{"id":"8dbacb5c.b323e8","type":"change","z":"4a1b3556.f7d3bc","name":"HOLD?","rules":[{"t":"set","p":"payload","pt":"msg","to":"MODE","tot":"flow"},{"t":"set","p":"topic","pt":"msg","to":"CONTROL","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":1090,"wires":[["d2f5757c.e19948"]]},{"id":"d2f5757c.e19948","type":"gate","z":"4a1b3556.f7d3bc","name":"","controlTopic":"CONTROL","defaultState":"closed","openCmd":"RELEASE","closeCmd":"HOLD","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":820,"y":1130,"wires":[["663fdf19.cb40e"]]},{"id":"35a7901b.22896","type":"link in","z":"4a1b3556.f7d3bc","name":"Test inputs","links":[],"x":520,"y":760,"wires":[["1523fda4.8aad7a"]],"l":true},{"id":"a297e51f.ac21b8","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["9fdd0ca7.ed7","cdab01c7.08a0b8"],"x":785,"y":1050,"wires":[["8dbacb5c.b323e8","b3a84423.c8628","94208a3e.abbfa8"]]},{"id":"9fdd0ca7.ed7","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["a297e51f.ac21b8"],"x":705,"y":770,"wires":[]},{"id":"aeafb108.0873e","type":"inject","z":"4a1b3556.f7d3bc","name":"Trip","topic":"TRAIN","payload":"TRIP","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":510,"y":680,"wires":[["1523fda4.8aad7a"]]},{"id":"dbf20726.bb05d","type":"fan","z":"4a1b3556.f7d3bc","x":1260,"y":1130,"wires":[["63a79633.73615","99815e07.1304e","561fb01b.b78e48"]]},{"id":"af6a5d3b.8c8cc8","type":"link out","z":"4a1b3556.f7d3bc","name":"Pulse","links":[],"x":1610,"y":940,"wires":[],"l":true},{"id":"5fabda69.45827c","type":"comment","z":"4a1b3556.f7d3bc","name":"Point status","info":"","x":2880,"y":740,"wires":[]},{"id":"39f7078c.ad93a","type":"debug","z":"4a1b3556.f7d3bc","name":"Point status","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":3190,"y":740,"wires":[]},{"id":"d71eb89a.9113d","type":"comment","z":"4a1b3556.f7d3bc","name":"Stop block entry if HOLD set","info":"","x":810,"y":1180,"wires":[]},{"id":"663fdf19.cb40e","type":"gate","z":"4a1b3556.f7d3bc","name":"","controlTopic":"CONTROL","defaultState":"closed","openCmd":"GO","closeCmd":"STOP","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":1010,"y":1130,"wires":[["dbf20726.bb05d"]]},{"id":"541198a1.9ae518","type":"debug","z":"4a1b3556.f7d3bc","name":"HOLD / POINT message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1080,"y":1000,"wires":[]},{"id":"7a02c7cc.977ec","type":"function","z":"4a1b3556.f7d3bc","name":"Ahead","func":"let x = \"\";\nlet p = flow.get('POINT');\nif (p == 'AHEAD')\n{\n    x = flow.get('AHEAD');\n    if (x == \"STOP\")\n    {\n        msg.payload = \"STOP\";\n    } else\n    {\n        msg.payload = \"GO\";\n    }\n} else\nif (p == 'TURN')\n{\n    x = flow.get('TURN');\n    if (x == \"LOWSPEED\")\n    {\n        msg.payload = \"STOP\";\n    } else\n    {\n        msg.payload = \"GO\";\n    }\n}\nmsg.topic = \"CONTROL\";\nreturn msg;\n","outputs":1,"noerr":0,"x":1010,"y":1090,"wires":[["663fdf19.cb40e","2e910189.84fb4e"]]},{"id":"b3a84423.c8628","type":"delay","z":"4a1b3556.f7d3bc","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1020,"y":1050,"wires":[["7a02c7cc.977ec"]]},{"id":"2e910189.84fb4e","type":"debug","z":"4a1b3556.f7d3bc","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1240,"y":1090,"wires":[]},{"id":"cca98bfa.d23","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["6afc817a.60b268"],"x":1845,"y":850,"wires":[]},{"id":"5f6a753d.45937c","type":"debug","z":"4a1b3556.f7d3bc","name":"Upstream track type","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":3220,"y":580,"wires":[]},{"id":"93653fd8.6ebe98","type":"debug","z":"4a1b3556.f7d3bc","name":"Top light","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":3180,"y":620,"wires":[]},{"id":"9441729a.9512a8","type":"debug","z":"4a1b3556.f7d3bc","name":"Bottom light","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":3190,"y":660,"wires":[]},{"id":"3d3a3253.409dfe","type":"debug","z":"4a1b3556.f7d3bc","name":"Small light","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":3190,"y":700,"wires":[]},{"id":"733fd106.a20d88","type":"template","z":"4a1b3556.f7d3bc","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Points are set to {{payload}}","output":"str","x":2610,"y":780,"wires":[["19f4ce3e.54c112"]]},{"id":"6e7e9e36.7c279","type":"delay","z":"4a1b3556.f7d3bc","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":2310,"y":780,"wires":[["a0bfd49c.441088"]]},{"id":"98dd15ba.a5994","type":"function","z":"4a1b3556.f7d3bc","name":"Hold","func":"let x = flow.get('POINT') || 0;\nvar p;\n//node.warn(\"X \" + x)\nflow.set('MODE','HOLD');\n\n\nif (x == 'AHEAD')\n{\n//    node.warn(\">>  AHEAD\");\n    msg = {'payload':'HOLD', 'topic':'AHEAD'};\n} else\nif (x == 'TURN')\n{\n//    node.warn(\">>  TURN\");\n    msg = {'payload':'HOLD', 'topic': 'POINTS'};\n}\nreturn msg;","outputs":1,"noerr":0,"x":900,"y":460,"wires":[["b3b280e2.645798"]]},{"id":"cb87fd5.635f","type":"link out","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["7cea5895.f16e4","f27f9559.2918a8","1aa0ceee.d22179","4fd436cc.743a5","e755b75b.a594a8","829dfacd.aac278"],"x":900,"y":720,"wires":[],"l":true},{"id":"91d7c3ef.946ce","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":720,"y":320,"wires":[["6bcb3259.53cb64"]]},{"id":"7cea5895.f16e4","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":580,"y":320,"wires":[["91d7c3ef.946ce"]],"l":true},{"id":"f27f9559.2918a8","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":660,"y":620,"wires":[["42712278.b4cc44"]],"l":true},{"id":"42712278.b4cc44","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":800,"y":620,"wires":[["9aaa983e.ac8758"]]},{"id":"1aa0ceee.d22179","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":750,"y":1000,"wires":[["94208a3e.abbfa8"]],"l":true},{"id":"94208a3e.abbfa8","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":890,"y":1000,"wires":[["541198a1.9ae518"]]},{"id":"4fd436cc.743a5","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":2790,"y":670,"wires":[["daf57362.31533","f2e4ddaf.afdb68","4bc8dec8.446f38","b17a207d.6b7bb","802d089d.d3de28","30cacd75.069662"]],"l":true},{"id":"daf57362.31533","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":780,"wires":[["39f7078c.ad93a"]]},{"id":"f2e4ddaf.afdb68","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":700,"wires":[["3d3a3253.409dfe"]]},{"id":"4bc8dec8.446f38","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":660,"wires":[["9441729a.9512a8"]]},{"id":"b17a207d.6b7bb","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":620,"wires":[["93653fd8.6ebe98"]]},{"id":"802d089d.d3de28","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":580,"wires":[["5f6a753d.45937c"]]},{"id":"8ef3c2bd.222aa8","type":"inject","z":"4a1b3556.f7d3bc","name":"Debug OFF","topic":"DEBUG","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":530,"y":820,"wires":[["1523fda4.8aad7a"]]},{"id":"9e2b1341.8238e","type":"inject","z":"4a1b3556.f7d3bc","name":"Debug ON","topic":"DEBUG","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":520,"y":860,"wires":[["1523fda4.8aad7a"]]},{"id":"705aa937.7e2e28","type":"catch","z":"4a1b3556.f7d3bc","name":"","scope":null,"uncaught":false,"x":2750,"y":820,"wires":[["30cacd75.069662"]]},{"id":"30cacd75.069662","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":3030,"y":820,"wires":[[]]},{"id":"eedbc890.a306d","type":"debug","z":"4a1b3556.f7d3bc","name":"****  HOLD RELEASE COMMAND ****","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1190,"y":550,"wires":[]},{"id":"e3ff941b.44d108","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"TURN","vt":"str"},{"t":"eq","v":"AHEAD","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":2610,"y":880,"wires":[["69fd4b3f.1ec6ec"],["5e1bb6ab.f08b6"]]},{"id":"5e1bb6ab.f08b6","type":"function","z":"4a1b3556.f7d3bc","name":"Straight icon","func":"//      Still need to rotate 90 degrees\n\nmsg = {'payload':'<i class=\"material-icons fa-rotate-90\">pause</i>'};\nreturn msg;\n","outputs":1,"noerr":0,"x":2770,"y":920,"wires":[["fed63556.3f50f"]]},{"id":"69fd4b3f.1ec6ec","type":"function","z":"4a1b3556.f7d3bc","name":"Turn icon","func":"//      Still need to rotate 90 degrees\n\nmsg = {'payload':'<i class=\"material-icons\">shuffle</i>'};\nreturn msg;\n","outputs":1,"noerr":0,"x":2760,"y":880,"wires":[["fed63556.3f50f"]]},{"id":"fed63556.3f50f","type":"fan","z":"4a1b3556.f7d3bc","x":2920,"y":880,"wires":[[]]},{"id":"78c3654a.ba0f5c","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"HOLD","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1310,"y":830,"wires":[["e9be75b2.b13c78"]]},{"id":"b76c3a13.5063e8","type":"change","z":"4a1b3556.f7d3bc","name":"Status?","rules":[{"t":"set","p":"payload","pt":"msg","to":"MODE","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":830,"wires":[["78c3654a.ba0f5c"]]},{"id":"6eafc356.6f4be4","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["63a79633.73615"],"x":2735,"y":1130,"wires":[["3c3d37fc.7fffa8"]]},{"id":"63a79633.73615","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["6eafc356.6f4be4"],"x":1375,"y":1130,"wires":[]},{"id":"3c3d37fc.7fffa8","type":"fan","z":"4a1b3556.f7d3bc","x":2920,"y":1130,"wires":[["d4532a83.d489d8"]]},{"id":"d4532a83.d489d8","type":"delay","z":"4a1b3556.f7d3bc","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":3070,"y":1030,"wires":[[]]},{"id":"e755b75b.a594a8","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":1260,"y":1180,"wires":[["99815e07.1304e"]],"l":true},{"id":"99815e07.1304e","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":1400,"y":1180,"wires":[["8feb332c.c8a738"]]},{"id":"8feb332c.c8a738","type":"debug","z":"4a1b3556.f7d3bc","name":"TRAIN MESSAGE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1570,"y":1180,"wires":[]},{"id":"829dfacd.aac278","type":"link in","z":"4a1b3556.f7d3bc","name":"DEBUG","links":["cb87fd5.635f"],"x":1750,"y":540,"wires":[["c82fba31.8ea91"]],"l":true},{"id":"c82fba31.8ea91","type":"gate","z":"4a1b3556.f7d3bc","name":"Debug","controlTopic":"DEBUG","defaultState":"closed","openCmd":"ON","closeCmd":"OFF","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":1890,"y":540,"wires":[["13541e80.3dc8aa"]]},{"id":"4b13a510.2aea9c","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["6afc817a.60b268"],"x":1505,"y":1090,"wires":[]},{"id":"561fb01b.b78e48","type":"function","z":"4a1b3556.f7d3bc","name":"","func":"msg = {payload:'STOP', topic:'CONTROL'};\nreturn msg;","outputs":1,"noerr":0,"x":1410,"y":1090,"wires":[["4b13a510.2aea9c"]]},{"id":"944bd3ec.485f88","type":"function","z":"4a1b3556.f7d3bc","name":"","func":"let x = flow.get('TRAIN');\nif (x == 'HELD')\n{\n    //\n    node.warn(\"Getting old value\");\n    //\n    msg.payload = \"TRIP\";\n    msg.topic = \"TRAIN\";\n    flow.set('TRAIN',null);\n    return msg;\n}\n","outputs":1,"noerr":0,"x":1110,"y":1180,"wires":[["dbf20726.bb05d"]]},{"id":"b782e7f.ea27698","type":"link in","z":"4a1b3556.f7d3bc","name":"","links":["cdab01c7.08a0b8"],"x":1005,"y":1180,"wires":[["944bd3ec.485f88"]]},{"id":"6f453bf2.302274","type":"switch","z":"4a1b3556.f7d3bc","name":"","property":"TRAIN","propertyType":"flow","rules":[{"t":"null"}],"checkall":"true","repair":false,"outputs":1,"x":1220,"y":430,"wires":[["24ce82bc.06e076"]]},{"id":"24ce82bc.06e076","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["6afc817a.60b268"],"x":1325,"y":430,"wires":[]},{"id":"d65eb24.dd192d","type":"link out","z":"4a1b3556.f7d3bc","name":"","links":["6afc817a.60b268"],"x":1185,"y":460,"wires":[]}]

I haven't got it (yet) working where it holds the train if the block is set to HOLD the train.. (Track closed)
It is nearly working, but I just haven't got it 100% working.

(I hope this works)

The actual flow is WAY too big to post.
Suggestions on what I can do?
.zip it?
(Are they allowed?)

The subflow only just fits.

Coming soon - pictures how to wire it all up.

This is the button part of the flow:

[{"id":"c92363c5.903898","type":"ui_text","z":"98e5f2ad.3b36f","group":"ef8035b0.379398","order":2,"width":"3","height":"1","name":"","label":"Signal 1 (top)","format":"<font color={{msg.colour.A}} ><i class=\"fa fa-circle fa-3x\" style=\"font-size:18px;\"></i></font>","layout":"row-spread","x":1380,"y":630,"wires":[]},{"id":"24691b60.f6c814","type":"ui_text","z":"98e5f2ad.3b36f","group":"ef8035b0.379398","order":3,"width":0,"height":0,"name":"","label":"Signal 1 (bottom)","format":"<font color={{msg.colour.B}} ><i class=\"fa fa-circle fa-3x\" style=\"font-size:18px;\"></i></font>","layout":"row-spread","x":1400,"y":670,"wires":[]},{"id":"2fd2d176.92314e","type":"ui_text","z":"98e5f2ad.3b36f","group":"ef8035b0.379398","order":4,"width":0,"height":0,"name":"","label":"Signal 1 (small)","format":"<font color={{msg.colour.C}} ><i class=\"fa fa-circle\" style=\"font-size:18px;\"></i></font>","layout":"row-spread","x":1390,"y":710,"wires":[]},{"id":"ad1d78fe.52f0a8","type":"function","z":"98e5f2ad.3b36f","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\n\n//  Look for a !X message to get values.\nif (msg.topic == \"SETUP\")     //Do this if the message is NOT \"X\"\n{\n    //\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    msg.topic = msg.topicSET;\n    msg.payload = msg.PayloadA;\n    msg.colour = msg.colourA;\n    msg.txt = msg.txtA;\n    msg.fontclr = msg.txtclrA;\n    return msg;\n}\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //  Condition A\n    msg.payload = context.get(\"PayloadA\");\n    msg.colour = context.get(\"ABGC\");\n    msg.txt = context.get(\"Atxt\");\n    msg.fontclr = context.get(\"AFC\");\n} else\n{\n    //  Condition B\n    msg.payload = context.get(\"PayloadB\");\n    msg.colour = context.get(\"BBGC\");\n    msg.txt = context.get(\"Btxt\");\n    msg.fontclr = context.get(\"BFC\");\n}\nif (context.get(\"Topic\") == \"~\")\n{\n    msg.topic = \"\";\n} else\n{\n    msg.topic = context.get(\"Topic\");\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":1380,"y":590,"wires":[["85833a31.f2053","40a1ada7.728b24"]]},{"id":"85833a31.f2053","type":"ui_button","z":"98e5f2ad.3b36f","name":"HOLD/Clear Button","group":"ef8035b0.379398","order":1,"width":"3","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":1400,"y":540,"wires":[["ad1d78fe.52f0a8"]]},{"id":"59ab87d9.cf94a","type":"inject","z":"98e5f2ad.3b36f","name":"Setup","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":1360,"y":460,"wires":[["be66e64d.13443"]]},{"id":"be66e64d.13443","type":"function","z":"98e5f2ad.3b36f","name":"Setup","func":"msg = {\n    \"colourA\": \"lime\",\n    \"colourB\": \"red\",\n    \"txtA\": \"Release\",\n    \"txtB\": \"Hold\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"white\",\n    \"payloadA\": \"RELEASE\",\n    \"payloadB\": \"HOLD\",\n    \"topicSET\": \"CONTROL\",\n    \"topic\": \"SETUP\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":1360,"y":500,"wires":[["ad1d78fe.52f0a8"]]},{"id":"e8de2f1f.d6c338","type":"delay","z":"98e5f2ad.3b36f","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1370,"y":780,"wires":[["40a1ada7.728b24"]]},{"id":"5ceaded4.f96ba","type":"function","z":"98e5f2ad.3b36f","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\n\n//  Look for a !X message to get values.\nif (msg.topic == \"SETUP\")     //Do this if the message is NOT \"X\"\n{\n    //\n    node.warn(\"Setting up\");\n    //\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    msg.topic = msg.topicSET;\n    msg.payload = msg.PayloadA;\n    msg.colour = msg.colourA;\n    msg.txt = msg.txtA;\n    msg.fontclr = msg.txtclrA;\n    return msg;\n}\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //  Condition A\n    msg.payload = context.get(\"PayloadA\");\n    msg.colour = context.get(\"ABGC\");\n    msg.txt = context.get(\"Atxt\");\n    msg.fontclr = context.get(\"AFC\");\n} else\n{\n    //  Condition B\n    msg.payload = context.get(\"PayloadB\");\n    msg.colour = context.get(\"BBGC\");\n    msg.txt = context.get(\"Btxt\");\n    msg.fontclr = context.get(\"BFC\");\n}\nif (context.get(\"Topic\") == \"~\")\n{\n    msg.topic = \"\";\n} else\n{\n    msg.topic = context.get(\"Topic\");\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":1160,"y":590,"wires":[["1520941e.7a9c2c","40a1ada7.728b24","124951d3.0611ce"]]},{"id":"1520941e.7a9c2c","type":"ui_button","z":"98e5f2ad.3b36f","name":"Point control Button","group":"ef8035b0.379398","order":5,"width":"2","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":1180,"y":540,"wires":[["5ceaded4.f96ba"]]},{"id":"a00c7396.fc635","type":"inject","z":"98e5f2ad.3b36f","name":"Setup","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":1140,"y":460,"wires":[["7bc87445.5ad3cc"]]},{"id":"7bc87445.5ad3cc","type":"function","z":"98e5f2ad.3b36f","name":"Setup","func":"msg = {\n    \"colourA\": \"lime\",\n    \"colourB\": \"yellow\",\n    \"txtA\": \"Straight\",\n    \"txtB\": \"Turn\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"black\",\n    \"payloadA\": \"AHEAD\",\n    \"payloadB\": \"TURN\",\n    \"topicSET\": \"CONTROL\",\n    \"topic\": \"SETUP\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":500,"wires":[["5ceaded4.f96ba"]]},{"id":"124951d3.0611ce","type":"debug","z":"98e5f2ad.3b36f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1110,"y":670,"wires":[]},{"id":"ef8035b0.379398","type":"ui_group","z":"","name":"Block 3","tab":"fcd38650.724718","order":4,"disp":true,"width":"3","collapse":false},{"id":"fcd38650.724718","type":"ui_tab","z":"","name":"Signal test 3","icon":"dashboard","order":43,"disabled":false,"hidden":false}]

Pictures coming soon.

Oh, and the reset (startup) part:

[{"id":"f22e464e.765668","type":"link out","z":"98e5f2ad.3b36f","name":"RESET","links":["9ac3c607.5bf47","f49c52d7.1768c8","1f0d24d.f47c7db","acfdd6ba.1f29d8","1365692f.f3063f","ff3a353.488fa48","f57aff02.676c58","931bb28e.401b48"],"x":280,"y":180,"wires":[],"l":true},{"id":"cb61bf6a.ac0998","type":"inject","z":"98e5f2ad.3b36f","name":"Clear (S)","topic":"AHEAD","payload":"CLEAR","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"4","x":100,"y":60,"wires":[["f22e464e.765668"]]},{"id":"9642474c.e081d8","type":"inject","z":"98e5f2ad.3b36f","name":"Ahead","topic":"CONTROL","payload":"AHEAD","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"4","x":110,"y":100,"wires":[["f22e464e.765668"]]},{"id":"6073f3a3.ec7184","type":"inject","z":"98e5f2ad.3b36f","name":"Release","topic":"CONTROL","payload":"RELEASE","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"4","x":100,"y":140,"wires":[["f22e464e.765668"]]},{"id":"2a2dac6e.0aaa94","type":"inject","z":"98e5f2ad.3b36f","name":"Hold","topic":"CONTROL","payload":"HOLD","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"2","x":90,"y":180,"wires":[["f22e464e.765668"]]}]

Pictures.

#1 the basic layout.

Screenshot from 2020-01-01 16-15-52

Although I have (by accident) included an extra delay node. Either could be deleted depending on how you want to do it.
(See pic #2)

As I said.....

Pic #3

A better layout of where the other nodes connect to the subflow.

Repeat as many times as you want/care. The output goes to the next one's input.

To get it all going, (using Pic #2 as reference) the right delay node input is to a input node that injects:
payload:TRIP, topic:TRAIN

Make sure you connect the reset part. That sets up all the subflows with default settings.

Lastly:
If you want to put a turn out (or points) add this bit of code to that block's code:

Turnout button:

[{"id":"5ceaded4.f96ba","type":"function","z":"98e5f2ad.3b36f","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\n\n//  Look for a !X message to get values.\nif (msg.topic == \"SETUP\")     //Do this if the message is NOT \"X\"\n{\n    //\n    node.warn(\"Setting up\");\n    //\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    msg.topic = msg.topicSET;\n    msg.payload = msg.PayloadA;\n    msg.colour = msg.colourA;\n    msg.txt = msg.txtA;\n    msg.fontclr = msg.txtclrA;\n    return msg;\n}\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //  Condition A\n    msg.payload = context.get(\"PayloadA\");\n    msg.colour = context.get(\"ABGC\");\n    msg.txt = context.get(\"Atxt\");\n    msg.fontclr = context.get(\"AFC\");\n} else\n{\n    //  Condition B\n    msg.payload = context.get(\"PayloadB\");\n    msg.colour = context.get(\"BBGC\");\n    msg.txt = context.get(\"Btxt\");\n    msg.fontclr = context.get(\"BFC\");\n}\nif (context.get(\"Topic\") == \"~\")\n{\n    msg.topic = \"\";\n} else\n{\n    msg.topic = context.get(\"Topic\");\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":1160,"y":590,"wires":[["1520941e.7a9c2c","40a1ada7.728b24","124951d3.0611ce"]]},{"id":"1520941e.7a9c2c","type":"ui_button","z":"98e5f2ad.3b36f","name":"Point control Button","group":"ef8035b0.379398","order":5,"width":"2","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":1180,"y":540,"wires":[["5ceaded4.f96ba"]]},{"id":"a00c7396.fc635","type":"inject","z":"98e5f2ad.3b36f","name":"Setup","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":1140,"y":460,"wires":[["7bc87445.5ad3cc"]]},{"id":"7bc87445.5ad3cc","type":"function","z":"98e5f2ad.3b36f","name":"Setup","func":"msg = {\n    \"colourA\": \"lime\",\n    \"colourB\": \"yellow\",\n    \"txtA\": \"Straight\",\n    \"txtB\": \"Turn\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"black\",\n    \"payloadA\": \"AHEAD\",\n    \"payloadB\": \"TURN\",\n    \"topicSET\": \"CONTROL\",\n    \"topic\": \"SETUP\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":500,"wires":[["5ceaded4.f96ba"]]},{"id":"ef8035b0.379398","type":"ui_group","z":"","name":"Block 3","tab":"fcd38650.724718","order":4,"disp":true,"width":"3","collapse":false},{"id":"fcd38650.724718","type":"ui_tab","z":"","name":"Signal test 3","icon":"dashboard","order":43,"disabled":false,"hidden":false}]

This is the bigger picture and the red square is the bit of code I posted.
(give or take the couple of extra debug nodes which were captured on the left side)

And this is a picture of the GUI (train about halfway along the screen.)

Going Right - > Left.

Woo - that's very impressive.
Sounds like you have invested a considerable amount of time and energy into this project.
Are you planning on making a scale model of part of the rail network in Sydney or are you just interested in the 'control' aspects? Either way, it sounds good fun and very challenging.

Before I retired I worked as a computer science lecturer teaching microelectronics and programming.
One project, a group of my students undertook, was to control the speed and direction of a model train using Pulse Width Modulation (PWM) and an H-bridge. They built a track-layout consisting of an outer and inner circular-rectangular track with eight points so a train could move from one track to another.

The points were opearted via a CAN bus and a set of PIC microcontrollers. They also had some track-side signals (just simple twin LEDs) and infra-red beams positioned across the track just before each signal. This enabled the position of the train on the track to be determined and for it to be controlled.

If I had the time to do this project again (with today's technology) I think I would put a small WiFi microcontoller on each train so it could be controlled from Node-RED using a super-duper dashboard.

I wish you every success with your exciting project.

PS: Happy New Year.

I am just naturally curious.

I would like a bit of help getting the train control part working.

This is about iteration 3 of the subflow.

Before I build this one, I sat down with a big piece of paper and drew a basic flow of how it works.

So you are in Sydney too. Good. Your thoughts on this:
I was at Strathfield station. Platform 3. I was going to Rhodes.
Looking west, at the end of the platform signal: Green Yellow.
The next signal - at the points - Green Yellow.
The next train was going west.

Why two Green Yellow signals?

Anyway......

Yeah, I forget the name of the system which was introduced early 80's. DCC - I think.
That allowed multiple trains on the same DC track.

Anyway, the subflow:
It has a few outputs:
1 - to the next downstream block.
2 - Top light
3 - Bottom light
4 - The little light
5 - Text indication of points at this block
6 - Graphic output for point status
7 - Train status output.

I guess output #1 could be used to control speed for that block.
Though there is a bit of contention about if the block is before of after the signal/code.
I think it would be ok if it is after (track to the right side) of the signal.
Then if the signal is STOP, the train could come into/onto that block at low speed.
Then when it gets to the signal; that is stored and so when the signal clears/reduces the train signal is sent to the next block (to the LEFT) of that signal.

But that is where I fall over. I have some of the code there, but something isn't working quite the way I want.

Oh, and sorry. Thanks. Happy new year to you too.

Why do you think that?
I live in the UK, so have no idea about the names of the stations you mentioned.

At the moment I don't have any spare time to wade through your flows, as I'm preparing a set of tutorials and projects for a new group of students that I'll be tutoring starting this month.

One thing I would suggest is getting a small sub-section working (as briefly looking at your flows it would appear that many of the blocks are replicated). So once you get the basics working then you can scale it up.

(Ooops. The bad parser is still active - obviously)

I'll need to track that down and code it out of the flow.

I think the signals are similar to English ones.

No rush or worries.

What is tripping me up is how it holds the state and then releases it when the RELEASE code is received, and back propagating the signals to the previous block.

I may need a bigger piece of paper. :wink:

But thanks, I shall try to cut it down to smaller pieces and see if I can catch where it is falling apart.

Couple of suggestions.

What you're trying to do is implement a 'control system' using a Node-RED flow.
So the first thing to do is work out a specification or algorithm that defines what should happen under certain conditions. You probably have this already on your piece of paper. Having a good 'spec' also means you can create a testbench to prove the system works under all conditions.

For a very basic control system it normally means... "when I have these inputs then create this output".
Just like having a logic gate to detect an input and produce an output.

In your situation you are dealing with a non-trivial control system that has 'states' as well as 'inputs', so the complexity increases. For example detecting if there is a train within a block, about to leave a block or whether the block is empty will affect the track-side signals.

Many real-life (control) situations like getting money out of a cash machine are really a simple state machine. You have to do things in a certain sequence in order to get to the final result and sometimes there may be more than one path to get to a certain point.

I'm a big fan of finite state machines (FSMs) as it's usually a fairly easy task to construct a (graphical) state diagram to show how you can navigate from one state to another. Once the state diagram is complete and providing there are no dead-ends or unreachable states - you can code it.
Which language you use to do this is up to you, but since we are talking about Node-RED then JavaScript is probably the best choice.

If you want to see a simple example of a FSM then have a look at the Mathematical Magic Machine, I published on Discourse over Christmas. Hope you find this useful.

Mathematical Magic Machine

I suppose that if you added lots of delay nodes, it could also run like a British Rail system :roll_eyes:

10 Likes

I don't think Node-RED can run that slowly :slight_smile:

6 Likes

ARGH!

(Stupid me - again)

At least I posted the sub-flow way back near the start.

Today I was getting curious on how to get it working better, and I stuffed up.

Ok, I'll get the sub-flow I posted and stick it back in.

News flash:
All the links inside the subflow aren't there.

Anyone have an idea why that is?
Unless I am missing something.

I'm kinda stuck now because I did such a good job of fixing it until it broke I don't seem able to get the original sub-flow back.

Surely by now you are keeping regular backups of your flow file.
Was the bit you are looking for in the flow you posted earlier?

1 Like

It is no good keeping backups if when I re-import them, they are corrupt, as happened from the forum.

When I re-import it, there are no internal links.

Is this a bug?

Possibly, but if you just replace the whole flow file with your last backup then you will be good to go. Are you using the projects feature? If so then just checkout the previous version.

(Oh boy am I going to cop it for this, but.....)

This is what I see when I boot and use FF.
(Note: ALL those windows are FF.)
(Each window has anywhere from 1 to . . . . . 50? tabs.)

Going to NR ALONE, I have OVER 50 tabs on the NUC.

Backups. Yeah. One day.