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
- Raspberry Pi
- NodeJS host
- Arduino Uno
- Servo control (ideal for PWM support)
- OLED display
- Transport for London API
- Train Schedules
- PubNub
- Low-latency messaging for remote control
- Johnny-Five.io
- JavaScript robotics framework
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
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.
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!
the original post is from http://www.internetoflego.com/train-scheduled-automation-2/
Leave a Reply
You must be logged in to post a comment.