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 = (ClimaticState) state;
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() * (1 - (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 = (ScreenSetPoint) obj;
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 }
|