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