001package jmri.jmrit.automat;
002
003import jmri.InstanceManager;
004import jmri.Sensor;
005import jmri.Turnout;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * This sample Automaton watches a Sensor, and adjusts the state of a Turnout so
011 * that it matches the Sensor's state.
012 * <p>
013 * The sensor and turnout id's are hardcoded, as this is an example of just the
014 * Automaton function. Adding a GUI to configure these would be
015 * straight-forward. The values could be passed via the constructor, or the
016 * constructor (which can run in any required thread) could invoke a dialog.
017 * <p>
018 * For test purposes, one of these objects can be created and invoked by a
019 * SampleAutomatonAction.
020 * <p>
021 * For more information on JMRI support for automation classes, please see the
022 * <a href="http://jmri.org/help/en/html/tools/automation/viaJava.shtml">JMRI
023 * Layout Automation in Java page</a>.
024 *
025 * @author Bob Jacobsen Copyright (C) 2003
026 * @see jmri.jmrit.automat.SampleAutomatonAction
027 */
028public class SampleAutomaton extends AbstractAutomaton {
029
030    /**
031     * References the turnout to be controlled
032     */
033    Turnout turnout;
034    /**
035     * References the sensor to be monitored
036     */
037    Sensor sensor;
038
039    /**
040     * By default, monitors sensor "31"
041     */
042    String sensorName = "31";
043
044    /**
045     * By default, controls turnout "26".
046     */
047    String turnoutName = "26";
048
049    /**
050     * This also sets the turnout to the current (initial) state to make sure
051     * everything is consistent at the start.
052     */
053    @Override
054    protected void init() {
055
056        log.info("SampleAutomaton monitors sensor {} and controls turnout {}", sensorName, turnoutName);
057
058        // get references to sample layout objects
059        turnout = InstanceManager.turnoutManagerInstance().
060                provideTurnout(turnoutName);
061
062        sensor = InstanceManager.sensorManagerInstance().
063                provideSensor(sensorName);
064
065        // set up the initial correlation
066        now = sensor.getKnownState();
067        setTurnout(now);
068    }
069
070    int now;
071
072    /**
073     * Watch "sensor", and when it changes adjust "turnout" to match.
074     *
075     * @return Always returns true to continue operation
076     */
077    @Override
078    protected boolean handle() {
079        log.debug("Waiting for state change");
080
081        // wait until the sensor changes state
082        waitSensorChange(now, sensor);
083
084        // get new value
085        now = sensor.getKnownState();
086        log.debug("Found new state: {}", now);
087
088        // match the turnout to the conditions
089        setTurnout(now);
090
091        return true;   // never terminate voluntarily
092    }
093
094    /**
095     * Set "turnout" to match the sensor state
096     *
097     * @param now The current value of the sensor state.
098     */
099    void setTurnout(int now) {
100        if (now == Sensor.ACTIVE) {
101            turnout.setCommandedState(Turnout.THROWN);
102        } else {
103            turnout.setCommandedState(Turnout.CLOSED);
104        }
105    }
106
107    // initialize logging
108    private final static Logger log = LoggerFactory.getLogger(SampleAutomaton.class);
109
110}