JMRI: Layout Automation in Java
The JMRI library provides a very powerful set of tools for automating your layout. If the tools built into PanelPro or the scripting capability aren't sufficient to do what you want, writing your own control program certainly will be.This page describes the JMRI Java classes that support writing "automation" code in Java. That's things like operating signals, running trains, and even subtle things like changing decoder sound volumes when a train goes into a tunnel.
- Introduction
-
The "Automat" class provides an easy way to write Java automation for your layout using JMRI.
The key class is AbstractAutomaton, which provides threading support to simplify custom automation code.
Key aspect: These run in a separate thread, so they can wait for something to happen while the rest of the program proceeds. Effectively, each Automat is a separate program running when it needs to.
There are several examples:
- SampleAutomaton - watches a Sensor, and adjusts the state of a Turnout so that it matches the Sensor's state.
- SampleAutomaton2 - watches a Sensor, and adjusts the momentum of a locomotive decoder using ops-mode programming when the sensor state changes.
- SampleAutomaton3 - runs a locomotive back and forth on a piece of track by watching two sensors, reversing the locomotive when they change state.
These can be started from the "Development" Menu of the JmriDemo application. Note that they may not do anything useful on your railroad, as they have block and locomotive numbers hard-coded. They're meant to be examples for your own programming, not useful tools.
- Controlling Locomotives
-
// get the throttle instance for short address 3
throttle = getThrottle(3, false);This code snippet assigns "short address 3" to the "throttle" variable (the "false" selects short address; long address would have been "true"). If this doesn't work for some reason, you'll get a periodic "still waiting for throttle" message in the Java window, and the program will wait.
- Interacting with the user
-
You can put up some message boxes directly from Java, but it takes a little code to do it. To simplify it at the start, I've added a "MsgFrame" helper class to the JMRI library.
To make a message box, you first make an object of the "MsgFrame" class:
MsgFrame box = new MsgFrame();
(You can call it whatever you'd like, of course). That line should go with the other declarations, e.g. right after the "DccThrottle throttle = null;" line.
Then, inside the test routines, there are a few things you can do. To show a message and wait for the user to click a "Continue" button, do:
box.show("my message text goes here", true);
The 2nd argument shows the "Continue button and waits if true, and just continues if false. So if you'd like to show a status message while the program continues to run, do:
box.show("status message text", false);
If you've done that, you can change the message with another "show", or you can make the box go away with:
box.hide();
Java actually has to do some work to pop the box and draw it. We don't want that to delay the main test program, so I've written this helper class to do all that kind of work as a 2nd, lower priority. You should be able to put messages up on the screen without significantly slowing operation down (unless the program waits for the "Continue" button to be pressed, of course). And waiting for "Continue" to be pressed won't stop the operation of the rest of the program.