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