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    /**
105     * Constant for the Target Intensity property.
106     */
107    String PROPERTY_TARGET_INTENSITY = "TargetIntensity";
108
109    /** {@inheritDoc} */
110    @Override
111    default boolean isConsistentState() {
112        return (getState() == DigitalIO.ON)
113                || (getState() == DigitalIO.OFF);
114    }
115
116    /** {@inheritDoc} */
117    @Override
118    @InvokeOnLayoutThread
119    default void setCommandedState(int s) {
120        setState(s);
121    }
122
123    /** {@inheritDoc} */
124    @Override
125    default int getCommandedState() {
126        return getState();
127    }
128
129    /** {@inheritDoc} */
130    @Override
131    default int getKnownState() {
132        return getState();
133    }
134
135    /** {@inheritDoc} */
136    @Override
137    @InvokeOnLayoutThread
138    default void requestUpdateFromLayout() {
139        // Do nothing
140    }
141
142    /**
143     * Set the demanded output state. Valid values are ON and OFF. ON
144     * corresponds to the maxIntensity setting, and OFF corresponds to
145     * minIntensity.
146     * <p>
147     * Bound parameter.
148     * <p>
149     * Note that the state may have other values, such as INTERMEDIATE or a form
150     * of transitioning, but that these may not be directly set.
151     *
152     * @param newState the new desired state
153     * @throws IllegalArgumentException if invalid newState provided
154     */
155    @Override
156    @InvokeOnLayoutThread
157    void setState(int newState);
158
159    /**
160     * Get the current state of the Light's output.
161     */
162    @Override
163    int getState();
164
165    // control types - types defined
166    int NO_CONTROL = 0x00;
167    int SENSOR_CONTROL = 0x01;
168    int FAST_CLOCK_CONTROL = 0x02;
169    int TURNOUT_STATUS_CONTROL = 0x03;
170    int TIMED_ON_CONTROL = 0x04;
171    int TWO_SENSOR_CONTROL = 0x05;
172
173    // LightControl information management methods
174     
175    /**
176     * Clears (removes) all LightControl objects for this light
177     */
178    void clearLightControls();
179
180    /** 
181     * Add a LightControl to this Light.
182     * <p>
183     * Duplicates are considered the same, hence not added
184     * @param c the light control to add.
185     */
186    void addLightControl(@Nonnull LightControl c);
187
188    /**
189     * @return a list of all LightControls
190     */
191    @Nonnull
192    List<LightControl> getLightControlList();
193
194    /**
195     * Set the Enabled property, which determines whether the control logic
196     * built in the light object is operating or not. Light objects are usually
197     * enabled.
198     *
199     * @param state true if control logic is enabled; false otherwise
200     */
201    @InvokeOnLayoutThread
202    void setEnabled(boolean state);
203
204    /**
205     * Get the Enabled property, which determines whether the control logic
206     * built in the light object is operating or not.
207     *
208     * @return true if control logic is enabled; false otherwise
209     */
210    boolean getEnabled();
211
212    /**
213     * Activates a Light. This method activates each LightControl, setting up a
214     * control mechanism, appropriate to its control type.
215     */
216    @InvokeOnLayoutThread
217    void activateLight();
218
219    /**
220     * Deactivates a Light. This method deactivates each LightControl, shutting
221     * down its control mechanism.
222     */
223    @InvokeOnLayoutThread
224    void deactivateLight();
225}