예제 #1
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var    sensorResult        = new SensorSample(this.SensorName);
            var    obsTime             = DateTime.Now;
            double elapsedSinceReading = (obsTime - this.startTime).TotalSeconds;
            int    count = this.countSinceLastRead;

            this.countSinceLastRead = 0;
            this.LogMessage($"Elapsed: {elapsedSinceReading}");
            this.LogMessage($"Tick Count: {count}");
            double average = this.CalculateSpeed(count, elapsedSinceReading);

            sensorResult.AddFinalObservation(this.maxGust, "WIND_GUST", ObservationUnits.KmPerHour);
            sensorResult.AddFinalObservation(average, "WIND_AVERAGE", ObservationUnits.KmPerHour);

            observation.WindAverage = average;
            observation.WindGust    = this.maxGust != -1 ? this.maxGust : average;

            this.startTime = obsTime;
            this.gustCount = 0;
            this.maxGust   = -1;

            this.LogTakeReadingComplete();

            return(sensorResult);
        }
예제 #2
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var result = new SensorSample(this.SensorName);

            var  lines   = File.ReadAllLines(this.pathForW1);
            int  i       = 0;
            bool success = false;

            while (!success && i++ < 3)
            {
                success = lines[0].Contains("YES");
                if (success)
                {
                    var rawTemp = lines[1].Split('=').Last();
                    var temp    = float.Parse(rawTemp) / 1000.0f;
                    result.AddFinalObservation(temp, "TEMPERATURE2", ObservationUnits.DegreesCelcius);
                    result.AddDiagnostic(lines[0]);
                    result.AddDiagnostic(lines[1]);
                    observation.Temperature2 = temp;
                }
            }

            this.LogTakeReadingComplete();
            return(result);
        }
예제 #3
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);

            var result = this.sensor.Read();

            if (result.Humidity.HasValue && result.Pressure.HasValue && result.Temperature.HasValue)
            {
                var pressure           = result.Pressure.Value;
                var temperature        = new Temperature(result.Temperature.Value.DegreesCelsius + this.calibrationOffset, UnitsNet.Units.TemperatureUnit.DegreeCelsius);
                var rawTemperature     = result.Temperature.Value;
                var humidity           = result.Humidity.Value;
                var actualAltitude     = new Length(this.altitudeInMeters, UnitsNet.Units.LengthUnit.Meter);
                var calculatedAltitude = WeatherHelper.CalculateAltitude(pressure, WeatherHelper.MeanSeaLevel, rawTemperature);

                double absHumidity             = WeatherHelper.CalculateAbsoluteHumidity(temperature, humidity).GramsPerCubicMeter;
                double dewPoint                = WeatherHelper.CalculateDewPoint(temperature, humidity).DegreesCelsius;
                double heatIndex               = WeatherHelper.CalculateHeatIndex(temperature, humidity).DegreesCelsius;
                double vapourPressure          = WeatherHelper.CalculateActualVaporPressure(temperature, humidity).Hectopascals;
                double barometricPressure      = WeatherHelper.CalculateBarometricPressure(pressure, temperature, actualAltitude, humidity).Hectopascals;
                double vapourPressureOverIce   = WeatherHelper.CalculateSaturatedVaporPressureOverIce(temperature).Hectopascals;
                double vapourPressureOverWater = WeatherHelper.CalculateSaturatedVaporPressureOverWater(temperature).Hectopascals;
                double seaLevelPressure        = WeatherHelper.CalculateSeaLevelPressure(pressure, actualAltitude, temperature).Hectopascals;

                sensorResult.AddFinalObservation(temperature.DegreesCelsius, "TEMPERATURE", ObservationUnits.DegreesCelcius);
                sensorResult.AddFinalObservation(pressure.Hectopascals, "PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(barometricPressure, "BAROMETRIC PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(seaLevelPressure, "SEA LEVEL PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(vapourPressureOverIce, "OVER ICE PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(vapourPressureOverWater, "OVER WATER PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(humidity.Percent, "RELATIVE HUMIDITY", ObservationUnits.Percentage);
                sensorResult.AddFinalObservation(absHumidity, "ABSOLUTE HUMIDITY", ObservationUnits.GramsPerCubicMeter);
                sensorResult.AddFinalObservation(vapourPressure, "VAPOUR PRESSURE", ObservationUnits.HectoPascal);
                sensorResult.AddFinalObservation(calculatedAltitude.Meters, "CALCULATED ALTITUDE", ObservationUnits.Meters);
                sensorResult.AddFinalObservation(actualAltitude.Meters, "ACTUAL ALTITUDE", ObservationUnits.Meters);
                sensorResult.AddFinalObservation(heatIndex, "HEAT INDEX", ObservationUnits.DegreesCelcius);
                sensorResult.AddFinalObservation(dewPoint, "DEW POINT", ObservationUnits.DegreesCelcius);

                observation.Temperature1       = temperature.DegreesCelsius;
                observation.Pressure           = pressure.Hectopascals;
                observation.BarometricPressure = barometricPressure;
                observation.SealevelPressure   = seaLevelPressure;
                observation.OverIcePressure    = vapourPressureOverIce;
                observation.OverWaterPressure  = vapourPressureOverWater;
                observation.RelativeHumidity   = humidity.Percent;
                observation.AbsoluteHumidity   = absHumidity;
                observation.ActualAltitude     = actualAltitude.Meters;
                observation.CalculatedAltitude = calculatedAltitude.Meters;
                observation.HeatIndex          = heatIndex;
                observation.DewPoint           = dewPoint;
            }

            this.LogTakeReadingComplete();
            return(sensorResult);
        }
예제 #4
0
        /// <summary>
        /// Calculates the corrected humidity.
        /// </summary>
        /// <param name="sensorResult">The sensor result to update.</param>
        /// <param name="calibrationData">Calibration data from calibration registers.</param>
        /// <param name="rawHumidity">Raw bytes read from register.</param>
        /// <param name="tFine">The correction temperature.</param>
        /// <returns>The humidity.</returns>
        public static double CalculateHumidity(SensorSample sensorResult, Dictionary <SensorDigit, int> calibrationData, int rawHumidity, double tFine)
        {
            sensorResult.AddIntermediateObservation(rawHumidity, "RAW HUMIDITY", ObservationUnits.Percentage);
            double humidity = tFine - 76800.0d;

            humidity = (rawHumidity - ((calibrationData[SensorDigit.DigitH4] * 64.0) + (calibrationData[SensorDigit.DigitH5] / 16384.0 * humidity)))
                       * (calibrationData[SensorDigit.DigitH2] / 65536.0 * (1.0 + (calibrationData[SensorDigit.DigitH6] / 67108864.0 * humidity
                                                                                   * (1.0 + (calibrationData[SensorDigit.DigitH3] / 67108864.0 * humidity)))));
            humidity *= 1.0 - (calibrationData[SensorDigit.DigitH2] * humidity / 524288.0);
            return(humidity);
        }
예제 #5
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);
            int count        = this.tipCount.GetAndReset();

            this.LogMessage($"rain:tick: {count}");
            sensorResult.AddFinalObservation(count * BUCKETSIZE, "PRECIPITATION", ObservationUnits.Millimeter);
            observation.Precipitation = count * BUCKETSIZE;
            this.LogTakeReadingComplete();
            return(sensorResult);
        }
예제 #6
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);

            lock (this.syncroot)
            {
                sensorResult.AddFinalObservation(this.uvacalc, "UVA", ObservationUnits.Default);
                sensorResult.AddFinalObservation(this.uvbcalc, "UVB", ObservationUnits.Default);
                sensorResult.AddFinalObservation(this.uvicalc, "UVI", ObservationUnits.Default);
                observation.UvA = this.uvacalc;
                observation.UvB = this.uvbcalc;
                observation.UvI = this.uvicalc;
            }

            this.LogTakeReadingComplete();
            return(sensorResult);
        }
예제 #7
0
        /// <summary>
        /// Calculates the corrected temperature.
        /// </summary>
        /// <param name="sensorResult">The sensor result to update.</param>
        /// <param name="calibrationData">Calibration data from calibration registers.</param>
        /// <param name="rawTemp">Raw temperature read from register.</param>
        /// <param name="tFine">The correction temperature.</param>
        /// <returns>The temperature.</returns>
        public static double CalculateTemperature(SensorSample sensorResult, Dictionary <SensorDigit, int> calibrationData, int rawTemp, out double tFine)
        {
            sensorResult.AddIntermediateObservation(rawTemp, "RAW TEMPERATURE", ObservationUnits.DegreesCelcius);
            var tempPart1 = ((rawTemp / 16384.0d) - (calibrationData[SensorDigit.DigitT1] / 1024.0d)) * calibrationData[SensorDigit.DigitT2];

            var tempPart2 = ((rawTemp / 131072.0d) - (calibrationData[SensorDigit.DigitT1] / 8192.0))
                            * ((rawTemp / 131072.0d) - (calibrationData[SensorDigit.DigitT1] / 8192.0d))
                            * calibrationData[SensorDigit.DigitT3];

            sensorResult.AddDiagnostic($"var1: {tempPart1}");
            sensorResult.AddDiagnostic($"var2: {tempPart2}");

            tFine = tempPart1 + tempPart2;
            sensorResult.AddDiagnostic($"tfine: {tFine}");

            double finalTemp = (tempPart1 + tempPart2) / 5120d;

            sensorResult.AddDiagnostic(string.Format("finaltemp: {0}", finalTemp));
            return(finalTemp);
        }
예제 #8
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);
            var data         = this.ReadRawBytes(CCS811ALGRESULTDATA, 4);

            sensorResult.AddDiagnostic(ByteOperations.PrintByteArray(data));

            var co2  = (data[0] << 8) | data[1];
            var tvoc = (data[2] << 8) | data[3];

            sensorResult.AddFinalObservation(co2, "CO2", ObservationUnits.PartsPerMillion);
            sensorResult.AddFinalObservation(tvoc, "TVOC", ObservationUnits.PartsPerBillion);
            observation.CO2  = co2;
            observation.TVOC = tvoc;

            this.LogTakeReadingComplete();

            return(sensorResult);
        }
예제 #9
0
        /// <summary>
        /// Calculates the corrected pressure.
        /// </summary>
        /// <param name="sensorResult">The sensor result to update.</param>
        /// <param name="calibrationData">Calibration data from calibration registers.</param>
        /// <param name="rawPressure">Raw bytes read from register.</param>
        /// <param name="tFine">The correction temperature.</param>
        /// <returns>The pressure.</returns>
        public static double CalculatePressure(SensorSample sensorResult, Dictionary <SensorDigit, int> calibrationData, int rawPressure, double tFine)
        {
            sensorResult.AddIntermediateObservation(rawPressure, "RAW PRESSURE", ObservationUnits.HectoPascal);

            double var1 = ((double)tFine / 2.0) - 64000.0;
            double var2 = var1 * var1 * calibrationData[SensorDigit.DigitP6] / 32768.0;

            var2 += var1 * calibrationData[SensorDigit.DigitP5] * 2.0;
            var2  = (var2 / 4.0) + (calibrationData[SensorDigit.DigitP4] * 65536.0);
            var1  = ((calibrationData[SensorDigit.DigitP3] * var1 * var1 / 524288.0) + (calibrationData[SensorDigit.DigitP2] * var1)) / 524288.0;
            var1  = (1.0 + (var1 / 32768.0)) * calibrationData[SensorDigit.DigitP1];
            double pressure = 1048576.0 - (double)rawPressure;

            pressure  = (pressure - (var2 / 4096.0)) * 6250.0 / var1;
            var1      = calibrationData[SensorDigit.DigitP9] * pressure * pressure / 2147483648.0;
            var2      = pressure * calibrationData[SensorDigit.DigitP8] / 32768.0;
            pressure += (var1 + var2 + calibrationData[SensorDigit.DigitP7]) / 16.0;

            // Convert to hectopascal
            return(pressure / 100d);
        }
예제 #10
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);

            if (this.sensor.TryReadGasData(out VolumeConcentration eCO2, out VolumeConcentration eTVOC, out ElectricCurrent curr, out int adc))
            {
                sensorResult.AddFinalObservation(eCO2.PartsPerMillion, "CO2", ObservationUnits.PartsPerMillion);
                sensorResult.AddFinalObservation(eTVOC.PartsPerBillion, "TVOC", ObservationUnits.PartsPerBillion);
                observation.CO2  = eCO2.PartsPerMillion;
                observation.TVOC = eTVOC.PartsPerBillion;
            }
            else
            {
                this.LogError("Error reading from CSS811");
            }

            this.LogTakeReadingComplete();

            return(sensorResult);
        }
예제 #11
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var    result           = new SensorSample(this.SensorName);
            double currentState     = this.adc.Read(0) / 1024.0d;
            double correctedVoltage = this.CorrectVoltage(currentState);
            var    windDirection    = this.GetDirection(correctedVoltage);

            if (windDirection != null)
            {
                this.LogMessage($"adc raw: {currentState}");
                this.LogMessage($"adc corrected reading: {correctedVoltage}");
                this.LogMessage($"wind direction: {windDirection.Direction} ({windDirection.Degrees})");
                result.AddFinalObservation(windDirection.Degrees, "WINDDIRECTION", ObservationUnits.Default);
                observation.WindDirection = windDirection.Degrees;
                this.LogTakeReadingComplete();
            }
            else
            {
                this.LogError("Windvane reading error");
            }

            return(result);
        }
예제 #12
0
 internal SourcedSensorSample(NodeAddress address, SensorSample sensorSample) : base(address)
 {
     SensorSample = sensorSample;
 }
 public FilterSample(IOconfFilter filter)
 {
     Filter = filter;
     Output = new SensorSample(filter.Name + "_filter");
 }
예제 #14
0
        public void AddGyroSample(Vector3 value, float time)
        {
            currentGyroSample.value = value;
            currentGyroSample.time  = time;

            float delta = time - previousGyroSample.time;

            //

            if (!isOrientationInitialized)
            {
                accelQ                   = AccelToQuaternion(currentAccelSample.value);
                previousFilterQ          = accelQ;
                isOrientationInitialized = true;
                return;
            }

            var deltaT = currentGyroSample.time -
                         previousGyroSample.time;

            // Convert gyro rotation vector to a quaternion delta.
            Quaternion gyroDeltaQ = GyroToQuaternionDelta(currentGyroSample.value, deltaT);

            // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.
            filterQ  = previousFilterQ;
            filterQ *= gyroDeltaQ;

            // Calculate the delta between the current estimated gravity and the real
            // gravity vector from accelerometer.
            Quaternion invFilterQ = new Quaternion();

            invFilterQ = filterQ;
            invFilterQ = Quaternion.Inverse(invFilterQ);

            estimatedGravity = new Vector3(0, 0, -1);
            estimatedGravity = ApplyQuaternion(invFilterQ, estimatedGravity);
            estimatedGravity.Normalize();

            measuredGravity = currentAccelSample.value;
            measuredGravity.Normalize();

            // Compare estimated gravity with measured gravity, get the delta quaternion
            // between the two.
            Quaternion deltaQ = new Quaternion();

            deltaQ.SetFromToRotation(estimatedGravity, measuredGravity);
            deltaQ = Quaternion.Inverse(deltaQ);

            // Calculate the SLERP target: current orientation plus the measured-estimated
            // quaternion delta.
            Quaternion targetQ = new Quaternion();

            targetQ  = filterQ;
            targetQ *= deltaQ;

            // SLERP factor: 0 is pure gyro, 1 is pure accel.
            filterQ         = Quaternion.Slerp(filterQ, targetQ, 1 - accelGyroFactor);
            previousFilterQ = filterQ;

            //

            previousGyroSample = currentGyroSample;
        }
예제 #15
0
        /// <inheritdoc/>
        public override ISensorSample TakeReading(WeatherObservation observation)
        {
            this.LogTakeReadingStart();
            var sensorResult = new SensorSample(this.SensorName);

            // Initialize for reading
            this.Device.Write(new byte[] { REGCONTROLHUM, OVERSAMPLEHUM });
            var control = GetControlCode();

            this.Device.Write(new byte[] { REGCONTROL, (byte)control });

            // Read calibaration data
            var cal1 = this.ReadBytes(0x88, 24);
            var cal2 = this.ReadBytes(0xA1, 1);
            var cal3 = this.ReadBytes(0xE1, 7);

            sensorResult.AddDiagnostic("Calibration data (1/2/3)");
            sensorResult.AddDiagnostic(ByteOperations.PrintByteArray(cal1));
            sensorResult.AddDiagnostic(ByteOperations.PrintByteArray(cal2));
            sensorResult.AddDiagnostic(ByteOperations.PrintByteArray(cal3));

            var calibrationData = ExtractcalibrationData(cal1, cal2, cal3);

            // Pause per spec
            var wait_time = GetWaitTime();

            Thread.Sleep((int)wait_time / 1000);

            // Read raw data
            var data = this.ReadBytes(REGDATA, 8);

            sensorResult.AddDiagnostic("Raw data");
            sensorResult.AddDiagnostic(ByteOperations.PrintByteArray(data));

            var    rawTemp        = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
            double rawTemperature = CalculateTemperature(sensorResult, calibrationData, rawTemp, out double tFine);

            // Refine pressure and adjust for temperature
            var    rawPressure   = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
            double pressureValue = CalculatePressure(sensorResult, calibrationData, rawPressure, tFine);

            // Refine humidity
            var    rawHumidity   = (data[6] << 8) | data[7];
            double humidityValue = CalculateHumidity(sensorResult, calibrationData, rawHumidity, tFine);

            sensorResult.AddFinalObservation(rawTemperature + this.calibrationOffset, "TEMPERATURE", ObservationUnits.DegreesCelcius);
            sensorResult.AddFinalObservation(pressureValue, "PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(humidityValue, "HUMIDITY", ObservationUnits.Percentage);

            var pressure    = new Pressure(pressureValue, UnitsNet.Units.PressureUnit.Hectopascal);
            var humidity    = new RelativeHumidity(humidityValue, UnitsNet.Units.RelativeHumidityUnit.Percent);
            var temperature = new Temperature(rawTemperature, UnitsNet.Units.TemperatureUnit.DegreeCelsius);

            var actualAltitude     = new Length(this.altitudeInMeters, UnitsNet.Units.LengthUnit.Meter);
            var altitudeCalculated = WeatherHelper.CalculateAltitude(pressure);

            double absHumidity             = WeatherHelper.CalculateAbsoluteHumidity(temperature, humidity).GramsPerCubicMeter;
            double dewPoint                = WeatherHelper.CalculateDewPoint(temperature, humidity).DegreesCelsius;
            double heatIndex               = WeatherHelper.CalculateHeatIndex(temperature, humidity).DegreesCelsius;
            double vapourPressure          = WeatherHelper.CalculateActualVaporPressure(temperature, humidity).Hectopascals;
            double barometricPressure      = WeatherHelper.CalculateBarometricPressure(pressure, temperature, actualAltitude, humidity).Hectopascals;
            double vapourPressureOverIce   = WeatherHelper.CalculateSaturatedVaporPressureOverIce(temperature).Hectopascals;
            double vapourPressureOverWater = WeatherHelper.CalculateSaturatedVaporPressureOverWater(temperature).Hectopascals;
            double seaLevelPressure        = WeatherHelper.CalculateSeaLevelPressure(pressure, actualAltitude, temperature).Hectopascals;

            sensorResult.AddFinalObservation(temperature.DegreesCelsius + this.calibrationOffset, "TEMPERATURE", ObservationUnits.DegreesCelcius);
            sensorResult.AddFinalObservation(pressure.Hectopascals, "PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(barometricPressure, "BAROMETRIC PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(seaLevelPressure, "SEA LEVEL PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(vapourPressureOverIce, "OVER ICE PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(vapourPressureOverWater, "OVER WATER PRESSURE", ObservationUnits.HectoPascal);
            sensorResult.AddFinalObservation(humidity.Percent, "RELATIVE HUMIDITY", ObservationUnits.Percentage);
            sensorResult.AddFinalObservation(absHumidity, "ABSOLUTE HUMIDITY", ObservationUnits.GramsPerCubicMeter);
            sensorResult.AddFinalObservation(vapourPressure, "VAPOUR PRESSURE", ObservationUnits.Percentage);
            sensorResult.AddFinalObservation(altitudeCalculated.Meters, "CALCULATED ALTITUDE", ObservationUnits.Meters);
            sensorResult.AddFinalObservation(actualAltitude.Meters, "ACTUAL ALTITUDE", ObservationUnits.Meters);
            sensorResult.AddFinalObservation(heatIndex, "HEAT INDEX", ObservationUnits.DegreesCelcius);
            sensorResult.AddFinalObservation(dewPoint, "DEW POINT", ObservationUnits.DegreesCelcius);

            observation.Temperature1       = temperature.DegreesCelsius + this.calibrationOffset;
            observation.Pressure           = pressure.Hectopascals;
            observation.BarometricPressure = barometricPressure;
            observation.SealevelPressure   = seaLevelPressure;
            observation.OverIcePressure    = vapourPressureOverIce;
            observation.OverWaterPressure  = vapourPressureOverWater;
            observation.RelativeHumidity   = humidity.Percent;
            observation.AbsoluteHumidity   = absHumidity;
            observation.ActualAltitude     = actualAltitude.Meters;
            observation.CalculatedAltitude = altitudeCalculated.Meters;
            observation.HeatIndex          = heatIndex;
            observation.DewPoint           = dewPoint;

            this.LogTakeReadingComplete();

            return(sensorResult);
        }