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 heater.
018 *
019 * @author Deepthought
020 *
021 */
022 @Immutable
023 public final class HeaterSetPoint implements Adjustable {
024
025 private static final Log logger = LogFactory.getLog(HeaterSetPoint.class);
026
027 /**
028 * The setting of this setpoint.
029 */
030 private final double setting;
031
032 /**
033 * Id of the temperature sensor.
034 */
035 private final SuperLinkID temperatureID;
036
037 /**
038 * Id of the humidity sensor.
039 */
040 private final SuperLinkID humidityID;
041
042 private static final double FACTOR_PER_MINUTE = 0.1;
043
044 /**
045 * Internal enum to describe possible adjustments.
046 */
047 private enum HeaterStep {
048 UP(1f), DOWN(-1f);
049
050 private double increment;
051
052 HeaterStep(double increment) {
053 this.increment = increment;
054 }
055
056 public double getIncrement() {
057 return increment;
058 }
059 }
060
061 /**
062 * Creates a new <code>HeaterSetPoint</code> with the specified setting.
063 *
064 * @param setting
065 * the setting
066 */
067 public HeaterSetPoint(final double setting) {
068 humidityID = SystemSettings.getHumidityID();
069 temperatureID = SystemSettings.getTemperatureID();
070 this.setting = setting;
071 }
072
073 /*
074 * (non-Javadoc)
075 *
076 * @see dk.deepthought.sidious.supportsystem.Adjustable#consequence(dk.deepthought.sidious.supportsystem.State,
077 * dk.deepthought.sidious.supportsystem.Step)
078 */
079 public State consequence(State state) {
080 if (logger.isDebugEnabled()) {
081 logger.debug("consequence(State state=" + state
082 + ") - start - setting=" + setting);
083 }
084 if (!(state instanceof ClimaticState)) {
085 String fail = "Input state must be a climatic state. - state=" + state;
086 logger.error(fail);
087 throw new IllegalArgumentException(fail);
088 }
089 int timestep = SystemSettings.getTimestep();
090 ClimaticState climaticState = (ClimaticState) state;
091 Collection<SensorInput> sensors = climaticState.getSensors();
092 Collection<SensorInput> newSensors = new ArrayList<SensorInput>();
093 // When temperature increases, humidity decreases
094 for (SensorInput input : sensors) {
095 if (input.getID().equals(temperatureID)) {
096 double temperature = input.getValue();
097 double delta = setting - temperature;
098 double newValue = temperature + timestep * FACTOR_PER_MINUTE
099 * delta;
100 newSensors.add(input.newInstanceWithNewValue(newValue));
101 } else if (input.getID().equals(humidityID)) {
102 double decreaseFactor = decreaseFactor(input.getValue());
103 newSensors.add(input.newInstanceWithNewValue(decreaseFactor));
104 } else {
105 newSensors.add(input);
106 }
107 }
108 State returnState = new ClimaticState(newSensors);
109 if (logger.isDebugEnabled()) {
110 logger.debug("consequence(State state=" + state
111 + ") - end - return value=" + returnState);
112 }
113 return returnState;
114 }
115
116 /**
117 * Calculates the humidity decrease factor with respect to the increase in
118 * temperature.
119 *
120 * @param humidity
121 * value of humidity
122 * @return the decrease factor
123 */
124 private double decreaseFactor(double humidity) {
125 //FIXME WTF?!?
126 //Vi sammenligner humidity med setting af heater?!?
127 double delta = setting - humidity;
128 double factor = -delta * 0.01 + humidity;
129 return factor;
130 }
131
132 /*
133 * (non-Javadoc)
134 *
135 * @see dk.deepthought.sidious.supportsystem.Adjustable#possibleAdjustments()
136 */
137 public Collection<Adjustable> possibleAdjustments() {
138 if (logger.isDebugEnabled()) {
139 logger.debug("possibleAdjustments() - start");
140 }
141
142 Collection<Adjustable> setpoints = new ArrayList<Adjustable>();
143 for (HeaterStep possibleDirection : HeaterStep.values()) {
144 double result = setting + possibleDirection.getIncrement();
145 assert result != Float.MAX_VALUE : "result exceeded Float.MAX_VALUE";
146 setpoints.add(new HeaterSetPoint(result));
147 }
148 logger.debug(setpoints.size() + " possible adjustments created");
149 return setpoints;
150 }
151
152 /*
153 * (non-Javadoc)
154 *
155 * @see dk.deepthought.sidious.supportsystem.Adjustable#getID()
156 */
157 public SuperLinkID getID() {
158 return SystemSettings.getHeaterSetPointID();
159 }
160
161 /*
162 * (non-Javadoc)
163 *
164 * @see dk.deepthought.sidious.supportsystem.Adjustable#getSetting()
165 */
166 public double getSetting() {
167 return setting;
168 }
169
170
171
172 /* (non-Javadoc)
173 * @see java.lang.Object#hashCode()
174 */
175 @Override
176 public int hashCode() {
177 final int PRIME = 31;
178 int result = 1;
179 long temp;
180 temp = Double.doubleToLongBits(setting);
181 result = PRIME * result + (int) (temp ^ (temp >>> 32));
182 return result;
183 }
184
185 /* (non-Javadoc)
186 * @see java.lang.Object#equals(java.lang.Object)
187 */
188 @Override
189 public boolean equals(Object obj) {
190 if (this == obj)
191 return true;
192 if (obj == null)
193 return false;
194 if (getClass() != obj.getClass())
195 return false;
196 final HeaterSetPoint other = (HeaterSetPoint) obj;
197 if (Double.doubleToLongBits(setting) != Double.doubleToLongBits(other.setting))
198 return false;
199 return true;
200 }
201
202 /*
203 * (non-Javadoc)
204 *
205 * @see java.lang.Object#toString()
206 */
207 @Override
208 public String toString() {
209 return getClass().getSimpleName() + "[setting=" + setting + "]";
210 }
211
212 }
|