Now that I have a train schedule system and a way to remotely control the track switch, it’s time for automation!

Goal

Use schedule data to automatically switch train track

Think Safety and “Do Not Disturb”

Technologies & Components

Overview

This project will build on two previous articles, Train Track Switch and Train Schedule Display. These projects use Node-RED as the piping for my IoT messaging systems, REST, MQTT & PubNub. By using data from other sensors and API feeds, I’m easily able redirect and perform logic to send to other IoT connected hardware.

This article will primarily focus on the additional flows needed to connect it all together.

Complete Node-RED Flow

Download flows via Gist

Train Track Switch

Train TFL Schedule

Train Track Switch

Using the LEGO Train Track Switch project, I can easily use this flow to control the track switch by receiving the train schedule and filtering out the next train or by using a UI switch/Inject node. The commands are then sent to another flow to check for safety status prior to switching the track.

LEGO train track switch powered by Arduino using Johnny-five.io on a Raspberry Pi running NodeJS

Track Switch Automation

The “trainschedule” PubNub channel will receive a message from the scheduling flow. If the station name matches, the train approaching next is analyzed. If it is going towards “Enfield”, then the command to send it straight should be sent. If its going to “Cheshunt” then the track should turn.

Function: Next Train

This function simply pulls in the next trains approaching and places them in an array. The first record trains[0] will be passed to the switch node.

Switch node

The switch node will then look at the schedule and determine which station is next. Based on that, it will send a message on the appropriate output to the Train Track Switch command functions.

Check if Train is Approaching

Before the track can safely be switched, we must first check a few things.

Is the train approaching?

Has the safety been manually set?

The real challenge was avoiding a crash. While experimenting with this, the track switched while the train was crossing. Doh! So now I have to detect if a train is on the track switch. Because I already did a Train Crossing article, I could use that sensor message to detect if the train was coming. The state will be stored in a flow context variable in Node-RED which can be compared against when it’s time to switch the track.

This Node-RED user guide really helped explain clever ways to use multiple inputs and save the state.

By storing the track command with the addition of the track crossing activity, I could pause the track switch command until the change was safe. I also add a “node.status” to identify its safety status from the flow editor, which is really handy.

Function: Safety Gate

// this function stores the state of two inputs, safety && command. If the // safety state is not safe, the command is stored until the safety state changes to // safe. The node will notify state status by color and text flow.set('state', flow.get('data') || {}); context.set('data', context.get('data') || {}); // check initial safety state if (flow.get('state.safety') === undefined){ node.status({fill:"yellow",shape:"ring",text:flow.get('state.safety')}); } // store all messages and update safety state color switch(msg.topic){ case "safety": // set safety state //context.data.safety = msg.payload; flow.set('data.safety', msg.payload); if (flow.get('state.safety') == "safe"){ node.status({fill:"green",shape:"ring",text:"safe"}); } if (flow.get('state.safety') == "unsafe"){ node.status({fill:"red",shape:"ring",text:"unsafe"}); } break; case "command": context.set('data.command', msg.payload); break; default: break; } if(flow.get('state.safety') == "safe"){ if(context.get('data.command') !== undefined){ // send command msg.payload = context.get('data.command'); context.set('data.command', undefined); // reset command data for next trigger }else{ //msg.payload = {"news":"safe, but no command available"}; } }else{ msg.payload = {"news":"unsafe to switch track"}; } return msg;

Crisis averted !

Do not Disturb and UI

I used the Node-RED-contrib-ui NPM module to build a simple UI. The toggle switch changes the direction of the track and the safety status is updated with state. There are also two buttons to toggle the safety state.

The safety gate also acts as a switch to disable the automation so that it doesn’t switch the track all day long… and drive my wife crazy hearing the servo and switch sound in the living room 😉 In addition, I placed a standard electrical switch inline of the source power to disable the servo. This provides a total override option.

TFL Schedule

The schedule is based off of the Train Schedule Display project, where the public Transport for London API is used to pull in the local train schedule.

Track Switch

FINALLY, to switch the track on schedule, I just need to pipe this data from the schedule flow into the “trainschedule” PubNub channel. This message is then sent to the Track Automation Flow above.

Summary

This project demonstrates the power of IoT by combining data feeds and send them to other connected systems. I’ve been able to re-use projects to easily extend their capabilities. This was only one example but other use cases could involve alerts, mobile apps, signally lights, etc.

It also illustrates the power of Node-RED as a controller for IoT systems and works similar to LEGO, where having a few basic components and some imagination, amazing creations can come together.

The citizens of IoL City now have an efficient train system that is automated and informative!

Gallery