001 package dk.deepthought.sidious.greenhouse;
002 
003 import net.jcip.annotations.Immutable;
004 
005 import org.apache.commons.logging.Log;
006 import org.apache.commons.logging.LogFactory;
007 
008 import dk.deepthought.sidious.supportsystem.SuperLinkID;
009 
010 /**
011  * This class represents a sensor input from the environment at a specific time.
012  <p>
013  * It holds the id and the value of the given sensor at given time.
014  
015  @author Deepthought
016  
017  */
018 @Immutable
019 public final class SensorInput {
020     /**
021      * Logger for this class
022      */
023     private static final Log logger = LogFactory.getLog(SensorInput.class);
024 
025     /**
026      * The id of the sensor this represent.
027      */
028     private final SuperLinkID superLinkID;
029 
030     /**
031      * Current value of this sensor.
032      */
033     private final double value;
034 
035     /**
036      * Creates a new <code>SensorInput</code> object from the specified
037      <code>SuperLinkID</code> and <code>value</code>.
038      
039      @param superLinkID
040      *            the SuperLink Identifier of this sensor
041      @param value
042      *            value of this sensor
043      */
044     public SensorInput(SuperLinkID superLinkID, double value) {
045         if (Double.isNaN(value)) {
046             logger.error("SensorInput(SuperLinkID superLinkID=" + superLinkID
047                     ", double value=" + value + ") - NaN not a legal value");
048             throw new IllegalArgumentException("NaN not a legal value");
049         }
050         this.superLinkID = superLinkID;
051         this.value = round(value);
052     }
053 
054     /**
055      * Rounds the specified value.
056      
057      @param val
058      *            the value to round
059      @return the rounded value
060      */
061     private double round(double val) {
062         return ((int) (val * 10)) 10d;
063     }
064 
065     /**
066      * Creates a new instance of this type of <code>SensorInput</code> (i.e.
067      * with the same id) with the specified new <code>value</code>.
068      
069      @param value
070      *            the value of the new instance
071      @return a new instance of this <code>SensorInput</code>
072      */
073     public SensorInput newInstanceWithNewValue(double value) {
074         if (logger.isDebugEnabled()) {
075             logger.debug("newInstanceWithNewValue(double value=" + value
076                     ") - start");
077         }
078 
079         SensorInput returnSensorInput = new SensorInput(superLinkID, value);
080         if (logger.isDebugEnabled()) {
081             logger.debug("newInstanceWithNewValue(double value=" + value
082                     ") - end - return value=" + returnSensorInput);
083         }
084         return returnSensorInput;
085     }
086 
087     /**
088      * Gets the value of this sensor.
089      
090      @return the value of this sensor
091      */
092     public double getValue() {
093         return value;
094     }
095 
096     /**
097      * Compares two sensor inputs on super link equality.
098      <p>
099      * Returns <code>true</code> if and only if the <code>SuperLinkID</code>
100      * specified sensor and this sensor are equal.
101      
102      @param sensor
103      *            the input sensor
104      @return <code>true</code> if sensors have matching SuperLinkID's
105      */
106     public boolean equalsOnSuperLinkID(SensorInput sensor) {
107         return superLinkID.equals(sensor.superLinkID);
108     }
109 
110     /**
111      * Returns the id of this sensor.
112      
113      @return the id of this sensor
114      */
115     public SuperLinkID getID() {
116         return superLinkID;
117     }
118 
119     /**
120      * Method hashes <i>only</i> on <code>SuperLinkID</code>
121      
122      @see java.lang.Object#hashCode()
123      */
124     @Override
125     public int hashCode() {
126         final int PRIME = 31;
127         int result = 1;
128         result = PRIME * result
129                 ((superLinkID == null: superLinkID.hashCode());
130         return result;
131     }
132 
133     /*
134      * (non-Javadoc)
135      
136      * @see java.lang.Object#equals(java.lang.Object)
137      */
138     @Override
139     public boolean equals(Object obj) {
140         if (this == obj) {
141             return true;
142         }
143         if (obj == null) {
144             return false;
145         }
146         if (getClass() != obj.getClass()) {
147             return false;
148         }
149         final SensorInput other = (SensorInputobj;
150         if (superLinkID == null) {
151             if (other.superLinkID != null) {
152                 return false;
153             }
154         else if (!superLinkID.equals(other.superLinkID)) {
155             return false;
156         }
157         if (Double.doubleToLongBits(value!= Double
158                 .doubleToLongBits(other.value)) {
159             return false;
160         }
161         return true;
162     }
163 
164     /*
165      * (non-Javadoc)
166      
167      * @see java.lang.Object#toString()
168      */
169     @Override
170     public String toString() {
171         return getClass().getSimpleName() "[id=" + superLinkID
172                 ", value=" + value + "]";
173     }
174 
175 }