001package jmri;
002
003import java.util.List;
004import javax.annotation.Nonnull;
005
006/**
007 * Represent a single visible Light on the physical layout.
008 * <p>
009 * Each Light may have one or more control mechanisms. Control mechanism types
010 * are defined here. If a Light has any controls, the information is contained
011 * in LightControl objects, which are referenced via that Light.
012 * <p>
013 * Lights have a state and an intensity.
014 * <p>
015 * The intensity of the hardware output is represented by the range from 0.0 to
016 * 1.0, with 1.0 being brightest.
017 * <p>
018 * The primary states are:
019 * <ul>
020 * <li>ON, corresponding to maximum intensity
021 * <li>INTERMEDIATE, some value between maximum and minimum
022 * <li>OFF, corresponding to minimum intensity
023 * </ul>
024 * The underlying hardware may provide just the ON/OFF two levels, or have a
025 * semi-continuous intensity setting with some number of steps.
026 * <p>
027 * The light has a TargetIntensity property which can be set directly. In
028 * addition, it has a CurrentIntensity property which may differ from
029 * TargetIntensity while the Light is being moved from one intensity to another.
030 * <p>
031 * Intensity is limited by MinIntensity and MaxIntensity parameters. Setting the
032 * state to ON sets the TargetIntensity to MinIntensity, and to OFF sets the
033 * TargetIntensity to MaxIntensity. Attempting to directly set the
034 * TargetIntensity outside the values of MinIntensity and MaxIntensity
035 * (inclusive) will result in the TargetIntensity being set to the relevant
036 * limit.
037 * <p>
038 * Because the actual light hardware has only finite resolution, the intensity
039 * value is mapped to the nearest setting. For example, in the special case of a
040 * two-state (on/off) Light, setting a TargetIntensity of more than 0.5 will
041 * turn the Light on, less than 0.5 will turn the light off.
042 * <p>
043 * Specific implementations will describe how the settings map to the particular
044 * hardware commands.
045 * <p>
046 * The transition rate is absolute; the intensity changes at a constant rate
047 * regardless of whether the change is a big one or a small one.
048 *
049 * <hr>
050 * This file is part of JMRI.
051 * <p>
052 * JMRI is free software; you can redistribute it and/or modify it under the
053 * terms of version 2 of the GNU General Public License as published by the Free
054 * Software Foundation. See the "COPYING" file for a copy of this license.
055 * <p>
056 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
057 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
058 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
059 *
060 * @author Dave Duchamp Copyright (C) 2004, 2010
061 * @author Ken Cameron Copyright (C) 2008
062 * @author Bob Jacobsen Copyright (C) 2008
063 */
064public interface Light extends DigitalIO {
065
066    /**
067     * State value indicating output intensity is less than maxIntensity and
068     * more than minIntensity, and no transition is in progress
069     */
070    static final int INTERMEDIATE = 0x08;
071
072    /**
073     * State value indicating output intensity is currently changing toward
074     * higher intensity, and will continue until full ON is reached
075     */
076    static final int TRANSITIONINGTOFULLON = 0x310;
077
078    /**
079     * State value indicating output intensity is currently changing toward
080     * higher intensity. The current transition will stop before full ON is
081     * reached.
082     */
083    static final int TRANSITIONINGHIGHER = 0x210;
084
085    /**
086     * State value indicating output intensity is currently changing toward
087     * lower intensity. The current transition will stop before full OFF is
088     * reached.
089     */
090    static final int TRANSITIONINGLOWER = 0x110;
091
092    /**
093     * State value indicating output intensity is currently changing toward
094     * lower intensity, and will continue until full OFF is reached
095     */
096    static final int TRANSITIONINGTOFULLOFF = 0x010;
097
098    /**
099     * State value mask representing status where output is changing due to a
100     * request to transition.
101     */
102    static final int TRANSITIONING = 0x010;
103    
104    /** {@inheritDoc} */
105    @Override
106    default boolean isConsistentState() {
107        return (getState() == DigitalIO.ON)
108                || (getState() == DigitalIO.OFF);
109    }
110    
111    /** {@inheritDoc} */
112    @Override
113    @InvokeOnLayoutThread
114    default void setCommandedState(int s) {
115        setState(s);
116    }
117    
118    /** {@inheritDoc} */
119    @Override
120    default int getCommandedState() {
121        return getState();
122    }
123    
124    /** {@inheritDoc} */
125    @Override
126    default int getKnownState() {
127        return getState();
128    }
129    
130    /** {@inheritDoc} */
131    @Override
132    @InvokeOnLayoutThread
133    default void requestUpdateFromLayout() {
134        // Do nothing
135    }
136
137    /**
138     * Set the demanded output state. Valid values are ON and OFF. ON
139     * corresponds to the maxIntensity setting, and OFF corresponds to
140     * minIntensity.
141     * <p>
142     * Bound parameter.
143     * <p>
144     * Note that the state may have other values, such as INTERMEDIATE or a form
145     * of transitioning, but that these may not be directly set.
146     *
147     * @param newState the new desired state
148     * @throws IllegalArgumentException if invalid newState provided
149     */
150    @Override
151    @InvokeOnLayoutThread
152    void setState(int newState);
153
154    /**
155     * Get the current state of the Light's output.
156     */
157    @Override
158    int getState();
159
160    // control types - types defined
161    int NO_CONTROL = 0x00;
162    int SENSOR_CONTROL = 0x01;
163    int FAST_CLOCK_CONTROL = 0x02;
164    int TURNOUT_STATUS_CONTROL = 0x03;
165    int TIMED_ON_CONTROL = 0x04;
166    int TWO_SENSOR_CONTROL = 0x05;
167
168    // LightControl information management methods
169     
170    /**
171     * Clears (removes) all LightControl objects for this light
172     */
173    void clearLightControls();
174
175    /** 
176     * Add a LightControl to this Light.
177     * <p>
178     * Duplicates are considered the same, hence not added
179     * @param c the light control to add.
180     */
181    void addLightControl(@Nonnull LightControl c);
182
183    /**
184     * @return a list of all LightControls
185     */
186    @Nonnull
187    List<LightControl> getLightControlList();
188
189    /**
190     * Set the Enabled property, which determines whether the control logic
191     * built in the light object is operating or not. Light objects are usually
192     * enabled.
193     *
194     * @param state true if control logic is enabled; false otherwise
195     */
196    @InvokeOnLayoutThread
197    void setEnabled(boolean state);
198
199    /**
200     * Get the Enabled property, which determines whether the control logic
201     * built in the light object is operating or not.
202     *
203     * @return true if control logic is enabled; false otherwise
204     */
205    boolean getEnabled();
206
207    /**
208     * Activates a Light. This method activates each LightControl, setting up a
209     * control mechanism, appropriate to its control type.
210     */
211    @InvokeOnLayoutThread
212    void activateLight();
213
214    /**
215     * Deactivates a Light. This method deactivates each LightControl, shutting
216     * down its control mechanism.
217     */
218    @InvokeOnLayoutThread
219    void deactivateLight();
220}