public AnalogTemperature( IAnalogInputPort analogInputPort, KnownSensorType sensorType, Calibration calibration = null ) { this.AnalogInputPort = analogInputPort; // // If the calibration object is null use the defaults for TMP35. // if (calibration == null) { calibration = new Calibration(); } switch (sensorType) { case KnownSensorType.TMP35: case KnownSensorType.LM35: case KnownSensorType.LM45: _yIntercept = 0; _millivoltsPerDegreeCentigrade = 10; break; case KnownSensorType.LM50: case KnownSensorType.TMP36: _yIntercept = 500; _millivoltsPerDegreeCentigrade = 10; break; case KnownSensorType.TMP37: _yIntercept = 0; _millivoltsPerDegreeCentigrade = 20; break; case KnownSensorType.Custom: _yIntercept = calibration.MillivoltsAtSampleReading - (calibration.SampleReading * calibration.MillivoltsAtSampleReading); _millivoltsPerDegreeCentigrade = calibration.MillivoltsPerDegreeCentigrade; break; default: throw new ArgumentException("Unknown sensor type", nameof(sensorType)); } // wire up our observable // have to convert from voltage to temp units for our consumers // this is where the magic is: this allows us to extend the IObservable // pattern through the sensor driver AnalogInputPort.Subscribe( new FilterableObserver <FloatChangeResult, float>( h => { var newTemp = VoltageToTemperature(h.New); var oldTemp = VoltageToTemperature(h.Old); this.Temperature = newTemp; // save state RaiseEventsAndNotify( new AtmosphericConditionChangeResult( new AtmosphericConditions(newTemp, 0, 0), new AtmosphericConditions(oldTemp, 0, 0) )); }) ); }