001 package dk.deepthought.sidious.greenhouse;
002 
003 import java.util.ArrayList;
004 import java.util.Collection;
005 
006 import net.jcip.annotations.Immutable;
007 
008 import org.apache.commons.logging.Log;
009 import org.apache.commons.logging.LogFactory;
010 
011 import dk.deepthought.sidious.supportsystem.Adjustable;
012 import dk.deepthought.sidious.supportsystem.State;
013 import dk.deepthought.sidious.supportsystem.SuperLinkID;
014 import dk.deepthought.sidious.supportsystem.SystemSettings;
015 
016 /**
017  * This class implements the abstraction of a setpoint of the screens.
018  
019  @author Deepthought
020  
021  */
022 @Immutable
023 public class ScreenSetPoint implements Adjustable {
024 
025     /**
026      * Logger for this class.
027      */
028     private static final Log logger = LogFactory.getLog(ScreenSetPoint.class);
029 
030     
031     /**
032      * The setting of this setpoint.
033      */
034     private final double setting;
035 
036     /**
037      * The id of the irradiance sensor.
038      */
039     private final SuperLinkID irradianceID;
040 
041     /**
042      * Internal enum to describe possible adjustments.
043      */
044     private enum ScreenStep {
045         UP(1f), DOWN(-1f)// Percent up and down
046 
047         private double increment;
048 
049         ScreenStep(double increment) {
050             this.increment = increment;
051         }
052 
053         public double getIncrement() {
054             return increment;
055         }
056     }
057 
058     /**
059      * Creates a new <code>ScreenSetPoint</code> with the specified setting.
060      <p>
061      * Input parameters should be between 0 and 100 percent. Parameters outside
062      * this will be rounded to nearest limit.
063      
064      @param setting
065      *            the setting
066      */
067     public ScreenSetPoint(double setting) {
068         irradianceID = SystemSettings.getIrradianceID();
069         if (setting > 100) {
070             setting = 100;
071         }
072         if (setting < 0) {
073             setting = 0;
074         }
075         this.setting = setting;
076     }
077 
078     /*
079      * (non-Javadoc)
080      
081      * @see dk.deepthought.sidious.supportsystem.Adjustable#consequence(dk.deepthought.sidious.supportsystem.State)
082      */
083     public State consequence(State state) {
084         if (!(state instanceof ClimaticState)) {
085             String fail = "Input state must be a climatic state. - state="
086                     + state;
087             logger.error(fail);
088             throw new IllegalArgumentException(fail);
089         }
090         ClimaticState cs = (ClimaticStatestate;
091         Collection<SensorInput> sensors = cs.getSensors();
092         Collection<SensorInput> newSensors = new ArrayList<SensorInput>();
093         for (SensorInput input : sensors) {
094             if (input.getID().equals(irradianceID)) {
095                 double newValue = input.getValue() ((setting / 100));
096                 newSensors.add(input.newInstanceWithNewValue(newValue));
097             else {
098                 newSensors.add(input);
099             }
100         }
101         return new ClimaticState(newSensors);
102     }
103 
104     /*
105      * (non-Javadoc)
106      
107      * @see dk.deepthought.sidious.supportsystem.Adjustable#possibleAdjustments()
108      */
109     public Collection<Adjustable> possibleAdjustments() {
110         Collection<Adjustable> setpoints = new ArrayList<Adjustable>();
111         for (ScreenStep possibleDirection : ScreenStep.values()) {
112             double result = setting + possibleDirection.getIncrement();
113             assert result != Float.MAX_VALUE : "result exceeded Float.MAX_VALUE";
114             int min = 0// Minimum value (windows closed)
115             int max = 100// Maximum value (windows opened up all the way)
116             if (result < min) {
117                 result = min;
118                 if (setting != min) {
119                     setpoints.add(new ScreenSetPoint(result));
120                 }
121             else if (result > max) {
122                 result = max;
123                 if (setting != max) {
124                     setpoints.add(new ScreenSetPoint(result));
125                 }
126             else {
127                 setpoints.add(new ScreenSetPoint(result));
128             }
129         }
130         return setpoints;
131     }
132 
133     /*
134      * (non-Javadoc)
135      
136      * @see dk.deepthought.sidious.supportsystem.Adjustable#getID()
137      */
138     public SuperLinkID getID() {
139         return SystemSettings.getScreenSetPointID();
140     }
141 
142     /*
143      * (non-Javadoc)
144      
145      * @see dk.deepthought.sidious.supportsystem.Adjustable#getSetting()
146      */
147     public double getSetting() {
148         return setting;
149     }
150 
151     /* (non-Javadoc)
152      * @see java.lang.Object#hashCode()
153      */
154     @Override
155     public int hashCode() {
156         final int PRIME = 31;
157         int result = 1;
158         long temp;
159         temp = Double.doubleToLongBits(setting);
160         result = PRIME * result + (int) (temp ^ (temp >>> 32));
161         return result;
162     }
163 
164     /* (non-Javadoc)
165      * @see java.lang.Object#equals(java.lang.Object)
166      */
167     @Override
168     public boolean equals(Object obj) {
169         if (this == obj)
170             return true;
171         if (obj == null)
172             return false;
173         if (getClass() != obj.getClass())
174             return false;
175         final ScreenSetPoint other = (ScreenSetPointobj;
176         if (Double.doubleToLongBits(setting!= Double.doubleToLongBits(other.setting))
177             return false;
178         return true;
179     }
180 
181     /*
182      * (non-Javadoc)
183      
184      * @see java.lang.Object#toString()
185      */
186     @Override
187     public String toString() {
188         return getClass().getSimpleName() "[setting=" + setting + "]";
189     }
190 }