001package jmri.jmrit.automat; 002 003import jmri.InstanceManager; 004import jmri.JmriException; 005import jmri.Programmer; 006import jmri.Sensor; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * This sample Automaton watches a Sensor, and adjusts the momentum of a 012 * locomotive using ops-mode programming when the sensor state changes. 013 * <p> 014 * The sensor and decoder are hardcoded, as this is an example of just the 015 * Automaton function. Adding a GUI to configure these would be 016 * straight-forward. The values could be passed via the constructor, or the 017 * constructor (which can run in any required thread) could invoke a dialog. 018 * <p> 019 * For test purposes, one of these objects can be created and invoked by a 020 * SampleAutomaton2Action. 021 * <p> 022 * For more information on JMRI support for automation classes, please see the 023 * <a href="http://jmri.org/help/en/html/tools/automation/viaJava.shtml">JMRI 024 * Layout Automation in Java page</a>. 025 * 026 * @author Bob Jacobsen Copyright (C) 2003 027 * @see jmri.jmrit.automat.SampleAutomaton2Action 028 */ 029public class SampleAutomaton2 extends AbstractAutomaton { 030 031 /** 032 * References the locomotive decoder to be controlled 033 */ 034 Programmer programmer; 035 /** 036 * References the sensor to be monitored 037 */ 038 Sensor sensor; 039 040 /** 041 * By default, monitors sensor "31" 042 */ 043 String sensorName = "31"; 044 045 /** 046 * By default, controls locomotive 1234(long). 047 */ 048 int locoNumber = 1234; 049 boolean locoLong = true; 050 051 /** 052 * By default, monitors sensor "32" and controls locomotive 1234(long). 053 * 054 */ 055 @Override 056 protected void init() { 057 // get references to sample layout objects 058 059 sensor = InstanceManager.sensorManagerInstance(). 060 provideSensor(sensorName); 061 062 programmer = InstanceManager.getDefault(jmri.AddressedProgrammerManager.class) 063 .getAddressedProgrammer(locoLong, locoNumber); 064 065 // set up the initial correlation 066 now = sensor.getKnownState(); 067 setMomentum(now); 068 } 069 070 int now; 071 072 /** 073 * Watch "sensor", and when it changes the momentum CV 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 decoder's momentum 089 setMomentum(now); 090 091 return true; // never terminate voluntarily 092 } 093 094 /** 095 * Set CV3, acceleration momentum, to match the sensor state. When the 096 * sensor is active, set the momentum to 30; when inactive, set the momentum 097 * to 0. 098 * 099 * @param now The current value of the sensor state. 100 */ 101 void setMomentum(int now) { 102 try { 103 if (now == Sensor.ACTIVE) { 104 programmer.writeCV("3", 30, null); 105 } else { 106 programmer.writeCV("3", 0, null); 107 } 108 } catch (JmriException e) { 109 log.error("exception setting turnout", e); 110 } 111 } 112 113 // initialize logging 114 private final static Logger log = LoggerFactory.getLogger(SampleAutomaton2.class); 115}