001package jmri;
002
003import javax.annotation.CheckForNull;
004
005/**
006 * General input device representation. Often subclassed for specific types of
007 * sensors.
008 *
009 * <hr>
010 * This file is part of JMRI.
011 * <p>
012 * JMRI is free software; you can redistribute it and/or modify it under the
013 * terms of version 2 of the GNU General Public License as published by the Free
014 * Software Foundation. See the "COPYING" file for a copy of this license.
015 * <p>
016 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
017 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
018 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
019 *
020 * @author Bob Jacobsen Copyright (C) 2001
021 */
022public interface Sensor extends DigitalIO {
023
024    // states are parameters; both closed and thrown is possible!
025    static final int ACTIVE = DigitalIO.ON;
026    static final int INACTIVE = DigitalIO.OFF;
027
028    // Max value for Debounce Parameter
029    static final Long MAX_DEBOUNCE = 9999999L;
030
031    /**
032     * String constant for the Active Timer property.
033     */
034    String PROPERTY_ACTIVE_TIMER = "ActiveTimer";
035
036    /**
037     * String constant for the InActive Timer property.
038     */
039    String PROPERTY_INACTIVE_TIMER = "InActiveTimer";
040
041    /**
042     * String constant for the Global Timer property.
043     */
044    String PROPERTY_GLOBAL_TIMER = "GlobalTimer";
045
046    /**
047     * String constant for the inverted property.
048     */
049    String PROPERTY_SENSOR_INVERTED = "inverted";
050
051    /** {@inheritDoc} */
052    @Override
053    default boolean isConsistentState() {
054        return true;
055    }
056    
057    /** {@inheritDoc} */
058    @Override
059    @InvokeOnLayoutThread
060    default void setCommandedState(int s) {
061        try {
062            setState(s);
063        } catch (JmriException ex) {
064            log.error("setCommandedState", ex);
065        }
066    }
067    
068    /** {@inheritDoc} */
069    @Override
070    default int getCommandedState() {
071        return getState();
072    }
073    
074    /**
075     * Set the known state on the layout. This might not always be available, or
076     * effective, depending on the limits of the underlying system and
077     * implementation.
078     *
079     * @param newState the state to set
080     * @throws jmri.JmriException if unable to set the state
081     */
082    @InvokeOnLayoutThread
083    void setKnownState(int newState) throws jmri.JmriException;
084
085    /**
086     * Control whether the actual sensor input is considered to be inverted,
087     * such that the normal electrical signal that normally results in an ACTIVE
088     * state now results in an INACTIVE state.
089     * <p>
090     * Changing this changes the state from ACTIVE to INACTIVE and vice-versa,
091     * with notifications; UNKNOWN and INCONSISTENT are left unchanged.
092     *
093     * @param inverted true if the sensor should be inverted; false otherwise
094     */
095    @InvokeOnLayoutThread
096    void setInverted(boolean inverted);
097
098    /**
099     * Get the inverted state.
100     *
101     * @return true if the electrical signal that normally results in an ACTIVE
102     *         state now results in an INACTIVE state; false otherwise
103     */
104    boolean getInverted();
105
106    /**
107     * Determine if sensor can be inverted. When a turnout is inverted the
108     * {@link #ACTIVE} and {@link #INACTIVE} states are inverted on the layout.
109     *
110     * @return true if can be inverted; false otherwise
111     */
112    boolean canInvert();
113
114    /**
115     * Remove references to and from this object, so that it can eventually be
116     * garbage-collected.
117     */
118    @Override
119    void dispose();  // remove _all_ connections!
120
121    /**
122     * Used to return the Raw state of a sensor prior to the known state of a
123     * sensor being set. The raw state value can be different from the known
124     * state when the sensor debounce option is used.
125     *
126     * @return raw state value
127     */
128    int getRawState();
129
130    /**
131     * Set the active debounce delay.
132     *
133     * @param timer delay in milliseconds; set to zero to de-activate debounce
134     */
135    void setSensorDebounceGoingActiveTimer(long timer);
136
137    /**
138     * Get the active debounce delay.
139     *
140     * @return delay in milliseconds
141     */
142    long getSensorDebounceGoingActiveTimer();
143
144    /**
145     * Set the inactive debounce delay.
146     *
147     * @param timer delay in milliseconds; set to zero to de-activate debounce
148     */
149    void setSensorDebounceGoingInActiveTimer(long timer);
150
151    /**
152     * Get the inactive debounce delay.
153     *
154     * @return delay in milliseconds
155     */
156    long getSensorDebounceGoingInActiveTimer();
157
158    /**
159     * Use the timers specified in the {@link jmri.SensorManager} for the
160     * debounce delay.
161     * @since 4.9.2
162     *
163     * @param flag true to set to current defaults if not previously true
164     */
165    void setUseDefaultTimerSettings(boolean flag);
166
167    /**
168     * Does this sensor use the default timers values? (A remarkably unfortunate
169     * name given the one above)
170     * @since 4.9.2
171     *
172     * @return true if using default debounce values from the
173     *         {@link jmri.SensorManager}
174     */
175    boolean getUseDefaultTimerSettings();
176
177    /**
178     * Some sensor boards also serve the function of being able to report back
179     * train identities via such methods as RailCom. The setting and creation of
180     * the reporter against the sensor should be done when the sensor is
181     * created. This information is not saved.
182     *
183     * @param re the reporter to associate with the sensor
184     */
185    void setReporter(@CheckForNull Reporter re);
186
187    /**
188     * Retrieve the reporter associated with this sensor if there is one.
189     *
190     * @return the reporter or null if there is no associated reporter
191     */
192    @CheckForNull
193    Reporter getReporter();
194
195    /*
196     * Some sensor types allow us to configure a pull up and/or pull down 
197     * resistor at runtime.  The PullResistance enum provides valid values
198     * for the pull resistance.  The short name is used in xml files.
199     */
200    enum PullResistance {
201        PULL_UP("up", "PullResistanceUp"), // NOI18N
202        PULL_DOWN("down", "PullResistanceDown"), // NOI18N
203        PULL_OFF("off", "PullResistanceOff"); // NOI18N
204
205        PullResistance(String shName, String peopleKey) {
206           this.shortName = shName;
207           this.peopleName = Bundle.getMessage(peopleKey);
208        }
209
210        String shortName;
211        String peopleName;
212
213        public String getShortName() {
214           return shortName;
215        }
216
217        public String getPeopleName() {
218           return peopleName;
219        }
220
221        static public PullResistance getByShortName(String shName) {
222            for (PullResistance p : PullResistance.values()) {
223                if (p.shortName.equals(shName)) {
224                    return p;
225                }
226            }
227            throw new java.lang.IllegalArgumentException("argument value " + shName + " not valid");
228        }
229
230        static public PullResistance getByPeopleName(String pName) {
231            for (PullResistance p : PullResistance.values()) {
232                if (p.peopleName.equals(pName)) {
233                    return p;
234                }
235            }
236            throw new java.lang.IllegalArgumentException("argument value " + pName + " not valid");
237        }
238 
239       @Override
240       public String toString(){
241          return( peopleName );
242       }
243
244    }
245
246    /**
247     * Set the pull resistance
248     *
249     * @param r PullResistance value to use.
250     */
251    @InvokeOnLayoutThread
252    void setPullResistance(PullResistance r);
253
254    /**
255     * Get the pull resistance
256     *
257     * @return the currently set PullResistance value.
258     */
259    PullResistance getPullResistance();
260
261    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SLF4J_LOGGER_SHOULD_BE_PRIVATE",
262        justification="Private not available in interface")
263    static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Sensor.class);
264
265}