Esempio n. 1
0
 private void ProcessExtraDewPoint(NameValueCollection data, WeatherStation station)
 {
     for (var i = 1; i <= 10; i++)
     {
         if (data["temp" + i + "f"] != null && data["humidity" + i] != null)
         {
             var dp = MeteoLib.DewPoint(ConvertUserTempToC(station.ExtraTemp[i]), station.ExtraHum[i]);
             station.ExtraDewPoint[i] = ConvertTempCToUser(dp);
         }
     }
 }
Esempio n. 2
0
        /// <summary>
        ///     Read current data and process it
        /// </summary>
        private void GetAndProcessData()
        {
            //   Curr Reading Loc
            // 0  Time Since Last Save
            // 1  Hum In
            // 2  Temp In
            // 3  "
            // 4  Hum Out
            // 5  Temp Out
            // 6  "
            // 7  Pressure
            // 8  "
            // 9  Wind Speed m/s
            // 10  Wind Gust m/s
            // 11  Speed and Gust top nibbles (Gust top nibble)
            // 12  Wind Dir
            // 13  Rain counter
            // 14  "
            // 15  status

            // 16 Solar (Lux)
            // 17 "
            // 18 "
            // 19 UV

            //var ci = new CultureInfo("en-GB");
            //System.Threading.Thread.CurrentThread.CurrentCulture = ci;


            var data = new byte[32];

            if (cumulus.SyncFOReads && !Synchronising)
            {
                if ((DateTime.Now - FOSensorClockTime).TotalDays > 1)
                {
                    // (re)synchronise data reads to try to avoid USB lockup problem

                    StartSynchronising();

                    return;
                }
                else
                {
                    // Check that were not within N seconds of the station updating memory
                    bool sensorclockOK = ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds)) % 48 >= (cumulus.FOReadAvoidPeriod - 1)) &&
                                         ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds)) % 48 <= (47 - cumulus.FOReadAvoidPeriod));
                    bool stationclockOK = ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds)) % 60 >= (cumulus.FOReadAvoidPeriod - 1)) &&
                                          ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds)) % 60 <= (59 - cumulus.FOReadAvoidPeriod));

                    if (!sensorclockOK || !stationclockOK)
                    {
                        if (!sensorclockOK)
                        {
                            cumulus.LogDebugMessage("Within " + cumulus.FOReadAvoidPeriod + " seconds of sensor data change, skipping read");
                        }

                        if (!stationclockOK)
                        {
                            cumulus.LogDebugMessage("Within " + cumulus.FOReadAvoidPeriod + " seconds of station clock minute change, skipping read");
                        }

                        return;
                    }
                }
            }

            // get the block of memory containing the current data location

            if (cumulus.DataLogging)
            {
                cumulus.LogMessage("Reading first block");
            }
            ReadAddress(0, data);

            int addr = (data[31] * 256) + data[30];

            if (cumulus.DataLogging)
            {
                cumulus.LogMessage("First block read, addr = " + addr.ToString("X8"));
            }

            if (addr != prevaddr)
            {
                // location has changed, skip this read to give it chance to update
                //cumulus.LogMessage("Location changed, skipping");
                if (SynchroPhase == 2)
                {
                    cumulus.LogDebugMessage("Address changed");
                    cumulus.LogDebugMessage("addr=" + addr.ToString("X4") + "previous=" + prevaddr.ToString("X4"));
                    FOStationClockTime = DateTime.Now;
                    StopSynchronising();
                }
            }
            else
            {
                if (cumulus.DataLogging)
                {
                    cumulus.LogMessage("Reading data, addr = " + addr.ToString("X8"));
                }

                ReadAddress(addr, data);

                if (cumulus.DataLogging)
                {
                    cumulus.LogMessage("Data read - " + BitConverter.ToString(data));
                }

                DateTime now = DateTime.Now;

                if (Synchronising)
                {
                    if (SynchroPhase == 1)
                    {
                        // phase 1 - sensor clock
                        bool datachanged = false;
                        // ReadCounter determines whether we actually process the data (every 10 seconds)
                        ReadCounter++;
                        if (hadfirstsyncdata)
                        {
                            for (int i = 0; i < 16; i++)
                            {
                                if (prevdata[i] != data[i])
                                {
                                    datachanged = true;
                                }
                            }

                            if (datachanged)
                            {
                                FOSensorClockTime = DateTime.Now;
                                SynchroPhase      = 2;
                            }
                        }
                    }
                    else
                    {
                        // Phase 2 - station clock
                        ReadCounter++;
                    }
                }

                hadfirstsyncdata = true;
                for (int i = 0; i < 16; i++)
                {
                    prevdata[i] = data[i];
                }

                if ((!Synchronising) || ((ReadCounter % 20) == 0))
                {
                    LatestFOReading = addr.ToString("X4") + ":";
                    for (int i = 0; i < 16; i++)
                    {
                        LatestFOReading = LatestFOReading + " " + data[i].ToString("X2");
                    }

                    if (cumulus.DataLogging)
                    {
                        cumulus.LogMessage(LatestFOReading);
                    }

                    // Indoor Humidity ====================================================
                    int inhum = data[1];
                    if ((inhum > 100) && (inhum != 255))
                    {
                        // bad value
                        cumulus.LogMessage("Ignoring bad data: inhum = " + inhum);
                    }
                    else
                    {
                        // 255 is the overflow value, when RH gets below 10% - use 10%
                        if (inhum == 255)
                        {
                            inhum = 10;
                        }

                        if (inhum > 0)
                        {
                            DoIndoorHumidity(inhum);
                        }
                    }

                    // Indoor temperature ===============================================
                    double intemp = ((data[2]) + (data[3] & 0x7F) * 256) / 10.0f;
                    var    sign   = (byte)(data[3] & 0x80);
                    if (sign == 0x80)
                    {
                        intemp = -intemp;
                    }

                    if ((intemp > -50) && (intemp < 50))
                    {
                        DoIndoorTemp(ConvertTempCToUser(intemp));
                    }

                    // Pressure =========================================================
                    double pressure = (data[7] + (data[8] * 256)) / 10.0f + pressureOffset;

                    if ((pressure < cumulus.EWminpressureMB) || (pressure > cumulus.EWmaxpressureMB))
                    {
                        // bad value
                        cumulus.LogMessage("Ignoring bad data: pressure = " + pressure.ToString());
                        cumulus.LogMessage("                   offset = " + EWpressureoffset.ToString());
                    }
                    else
                    {
                        if ((previouspress == 9999) || (Math.Abs(pressure - previouspress) < cumulus.EWpressurediff))
                        {
                            previouspress = pressure;

                            DoPressure(ConvertPressMBToUser(pressure), now);
                            // Get station pressure in hPa by subtracting offset and calibrating
                            // EWpressure offset is difference between rel and abs in hPa
                            // PressOffset is user calibration in user units.
                            pressure        = pressure - pressureOffset + PressureHPa(cumulus.PressOffset);
                            StationPressure = ConvertPressMBToUser(pressure);
                        }
                        else
                        {
                            LogSpikeRemoval("Pressure difference greater than specified; reading ignored");
                            LogSpikeRemoval("Old value = " + previouspress.ToString("F1") + " New value = " + pressure.ToString("F1") + " EWpressurediff = " +
                                            cumulus.EWpressurediff.ToString("F1"));
                        }

                        UpdatePressureTrendString();
                        UpdateStatusPanel(now);
                        DoForecast("", false);
                    }
                    var status = data[15];
                    if ((status & 0x40) != 0)
                    {
                        SensorContactLost = true;
                        cumulus.LogMessage("Sensor contact lost; ignoring outdoor data");
                    }
                    else
                    {
                        SensorContactLost = false;
                        // Outdoor Humidity ===================================================
                        int outhum = data[4];
                        if ((outhum > 100) && (outhum != 255))
                        {
                            // bad value
                            cumulus.LogMessage("Ignoring bad data: outhum = " + outhum);
                        }
                        else
                        {
                            // 255 is the overflow value, when RH gets below 10% - use 10%
                            if (outhum == 255)
                            {
                                outhum = 10;
                            }

                            if (outhum > 0)
                            {
                                if ((previoushum == 999) || (Math.Abs(outhum - previoushum) < cumulus.EWhumiditydiff))
                                {
                                    previoushum = outhum;
                                    DoOutdoorHumidity(outhum, now);
                                }
                                else
                                {
                                    LogSpikeRemoval("Humidity difference greater than specified; reading ignored");
                                    LogSpikeRemoval("Old value = " + previoushum + " New value = " + outhum + " EWhumiditydiff = " + cumulus.EWhumiditydiff.ToString("F1"));
                                }
                            }
                        }

                        // Wind =============================================================
                        double gust      = (data[10] + ((data[11] & 0xF0) * 16)) / 10.0f;
                        double windspeed = (data[9] + ((data[11] & 0x0F) * 256)) / 10.0f;
                        var    winddir   = (int)(data[12] * 22.5f);

                        if ((gust > 60) || (gust < 0))
                        {
                            // bad value
                            cumulus.LogMessage("Ignoring bad data: gust = " + gust.ToString());
                        }
                        else if ((windspeed > 60) || (windspeed < 0))
                        {
                            // bad value
                            cumulus.LogMessage("Ignoring bad data: speed = " + gust.ToString());
                        }
                        else
                        {
                            if (((previousgust == 999) || (Math.Abs(gust - previousgust) < cumulus.EWgustdiff)) &&
                                ((previouswind == 999) || (Math.Abs(windspeed - previouswind) < cumulus.EWwinddiff)))
                            {
                                previousgust = gust;
                                previouswind = windspeed;
                                DoWind(ConvertWindMSToUser(gust), winddir, ConvertWindMSToUser(windspeed), now);
                            }
                            else
                            {
                                LogSpikeRemoval("Wind or gust difference greater than specified; reading ignored");
                                LogSpikeRemoval("Gust: Old value = " + previousgust.ToString("F1") + " New value = " + gust.ToString("F1") + " EWgustdiff = " +
                                                cumulus.EWgustdiff.ToString("F1"));
                                LogSpikeRemoval("Wind: Old value = " + previouswind.ToString("F1") + " New value = " + windspeed.ToString("F1") + " EWwinddiff = " +
                                                cumulus.EWwinddiff.ToString("F1"));
                            }
                        }

                        // Outdoor Temperature ==============================================
                        double outtemp = ((data[5]) + (data[6] & 0x7F) * 256) / 10.0f;
                        sign = (byte)(data[6] & 0x80);
                        if (sign == 0x80)
                        {
                            outtemp = -outtemp;
                        }

                        if ((outtemp < -50) || (outtemp > 70))
                        {
                            // bad value
                            cumulus.LogMessage("Ignoring bad data: outtemp = " + outtemp);
                        }
                        else
                        {
                            if ((previoustemp == 999) || (Math.Abs(outtemp - previoustemp) < cumulus.EWtempdiff))
                            {
                                previoustemp = outtemp;

                                DoOutdoorTemp(ConvertTempCToUser(outtemp), now);

                                // Use current humidity for dewpoint
                                if (OutdoorHumidity > 0)
                                {
                                    OutdoorDewpoint = ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature), OutdoorHumidity));

                                    CheckForDewpointHighLow(now);
                                }
                                ;

                                // calculate wind chill
                                if ((outtemp > -50) || (outtemp < 70))
                                {
                                    // The 'global average speed will have been determined by the call of DoWind
                                    // so use that in the wind chill calculation
                                    double avgspeedKPH = ConvertUserWindToKPH(WindAverage);

                                    // windinMPH = calibwind * 2.23693629;
                                    // calculate wind chill from calibrated C temp and calibrated win in KPH
                                    double val = MeteoLib.WindChill(ConvertUserTempToC(OutdoorTemperature), avgspeedKPH);

                                    DoWindChill(ConvertTempCToUser(val), now);
                                }

                                DoApparentTemp(now);
                            }
                            else
                            {
                                LogSpikeRemoval("Temp difference greater than specified; reading ignored");
                                LogSpikeRemoval("Old value = " + previoustemp + " New value = " + outtemp + " EWtempdiff = " + cumulus.EWtempdiff);
                            }
                        }

                        // Rain ============================================================
                        int raintot = data[13] + (data[14] * 256);
                        if (prevraintotal == -1)
                        {
                            // first reading
                            prevraintotal = raintot;
                            cumulus.LogMessage("Rain total count from station = " + raintot);
                        }

                        int raindiff = Math.Abs(raintot - prevraintotal);

                        if (raindiff > cumulus.EWMaxRainTipDiff)
                        {
                            cumulus.LogMessage("Warning: large difference in rain gauge tip count: " + raindiff);

                            ignoreraincount++;

                            if (ignoreraincount == 6)
                            {
                                cumulus.LogMessage("Six consecutive readings; accepting value. Adjusting start of day figure to compensate");
                                raindaystart = raindaystart + (raindiff * 0.3);
                                // adjust current rain total counter
                                Raincounter = Raincounter + (raindiff * 0.3);
                                cumulus.LogMessage("Setting raindaystart to " + raindaystart);
                                ignoreraincount = 0;
                            }
                            else
                            {
                                cumulus.LogMessage("Ignoring reading " + ignoreraincount);
                            }
                        }
                        else
                        {
                            ignoreraincount = 0;
                        }

                        if (ignoreraincount == 0)
                        {
                            DoRain(ConvertRainMMToUser(raintot * 0.3), -1, now);
                            prevraintotal = raintot;
                        }

                        // Solar/UV
                        if (hasSolar)
                        {
                            LightValue = (data[16] + (data[17] * 256) + (data[18] * 65536)) / 10.0;

                            if (LightValue < 300000)
                            {
                                DoSolarRad((int)(LightValue * cumulus.LuxToWM2), now);
                            }

                            int UVreading = data[19];

                            if (UVreading != 255)
                            {
                                DoUV(UVreading, now);
                            }
                        }
                    }
                }
            }

            prevaddr = addr;
        }
Esempio n. 3
0
        private void processHistoryData()
        {
            int totalentries = datalist.Count;

            cumulus.LogMessage("Processing history data, number of entries = " + totalentries);

            int rollHour = Math.Abs(cumulus.GetHourInc());

            int luhour = cumulus.LastUpdateTime.Hour;

            bool rolloverdone = luhour == rollHour;

            bool midnightraindone = luhour == 0;

            while (datalist.Count > 0)
            {
                HistoryData historydata = datalist[datalist.Count - 1];

                DateTime timestamp = historydata.timestamp;

                cumulus.LogMessage("Processing data for " + timestamp);

                int h = timestamp.Hour;

                //  if outside rollover hour, rollover yet to be done
                if (h != rollHour)
                {
                    rolloverdone = false;
                }

                // In rollover hour and rollover not yet done
                if ((h == rollHour) && !rolloverdone)
                {
                    // do rollover
                    cumulus.LogMessage("Day rollover " + timestamp.ToShortTimeString());
                    DayReset(timestamp);

                    rolloverdone = true;
                }

                // Not in midnight hour, midnight rain yet to be done
                if (h != 0)
                {
                    midnightraindone = false;
                }

                // In midnight hour and midnight rain (and sun) not yet done
                if ((h == 0) && !midnightraindone)
                {
                    ResetMidnightRain(timestamp);
                    ResetSunshineHours();
                    midnightraindone = true;
                }

                // Indoor Humidity ======================================================
                if ((historydata.inHum > 100) && (historydata.inHum != 255))
                {
                    cumulus.LogMessage("Ignoring bad data: inhum = " + historydata.inHum);
                }
                else if ((historydata.inHum > 0) && (historydata.inHum != 255))
                {
                    // 255 is the overflow value, when RH gets below 10% - ignore
                    DoIndoorHumidity(historydata.inHum);
                }

                // Indoor Temperature ===================================================
                if ((historydata.inTemp > -50) && (historydata.inTemp < 50))
                {
                    DoIndoorTemp(ConvertTempCToUser(historydata.inTemp));
                }

                // Pressure =============================================================

                if ((historydata.pressure < cumulus.EWminpressureMB) || (historydata.pressure > cumulus.EWmaxpressureMB))
                {
                    cumulus.LogMessage("Ignoring bad data: pressure = " + historydata.pressure);
                    cumulus.LogMessage("                   offset = " + pressureOffset);
                }
                else
                {
                    DoPressure(ConvertPressMBToUser(historydata.pressure), timestamp);
                }

                if (historydata.SensorContactLost)
                {
                    cumulus.LogMessage("Sensor contact lost; ignoring outdoor data");
                }
                else
                {
                    // Outdoor Humidity =====================================================
                    if ((historydata.outHum > 100) && (historydata.outHum != 255))
                    {
                        cumulus.LogMessage("Ignoring bad data: outhum = " + historydata.outHum);
                    }
                    else if ((historydata.outHum > 0) && (historydata.outHum != 255))
                    {
                        // 255 is the overflow value, when RH gets below 10% - ignore
                        DoOutdoorHumidity(historydata.outHum, timestamp);
                    }

                    // Wind =================================================================
                    if ((historydata.windGust > 60) || (historydata.windGust < 0))
                    {
                        cumulus.LogMessage("Ignoring bad data: gust = " + historydata.windGust);
                    }
                    else if ((historydata.windSpeed > 60) || (historydata.windSpeed < 0))
                    {
                        cumulus.LogMessage("Ignoring bad data: speed = " + historydata.windSpeed);
                    }
                    {
                        DoWind(ConvertWindMSToUser(historydata.windGust), historydata.windBearing, ConvertWindMSToUser(historydata.windSpeed), timestamp);
                    }

                    // Outdoor Temperature ==================================================
                    if ((historydata.outTemp < -50) || (historydata.outTemp > 70))
                    {
                        cumulus.LogMessage("Ignoring bad data: outtemp = " + historydata.outTemp);
                    }
                    else
                    {
                        DoOutdoorTemp(ConvertTempCToUser(historydata.outTemp), timestamp);
                        // add in 'archivePeriod' minutes worth of temperature to the temp samples
                        tempsamplestoday = tempsamplestoday + historydata.interval;
                        TempTotalToday   = TempTotalToday + (OutdoorTemperature * historydata.interval);
                    }

                    // update chill hours
                    if (OutdoorTemperature < cumulus.ChillHourThreshold)
                    {
                        // add 1 minute to chill hours
                        ChillHours = ChillHours + (historydata.interval / 60);
                    }

                    int raindiff;
                    if (prevraintotal == -1)
                    {
                        raindiff = 0;
                    }
                    else
                    {
                        raindiff = historydata.rainCounter - prevraintotal;
                    }

                    // record time of last rain tip, to use in
                    // normal running rain rate calc NB rain rate calc not currently used
                    if (raindiff > 0)
                    {
                        lastraintip = timestamp;

                        raininlasttip = raindiff;
                    }
                    else
                    {
                        lastraintip = DateTime.MinValue;

                        raininlasttip = 0;
                    }

                    double rainrate;

                    if (raindiff > 100)
                    {
                        cumulus.LogMessage("Warning: large increase in rain gauge tip count: " + raindiff);
                        rainrate = 0;
                    }
                    else
                    {
                        if (historydata.interval > 0)
                        {
                            rainrate = ConvertRainMMToUser((raindiff * 0.3) * (60.0 / historydata.interval));
                        }
                        else
                        {
                            rainrate = 0;
                        }
                    }

                    DoRain(ConvertRainMMToUser(historydata.rainCounter * 0.3), rainrate, timestamp);

                    prevraintotal = historydata.rainCounter;

                    OutdoorDewpoint = ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature), OutdoorHumidity));

                    CheckForDewpointHighLow(timestamp);


                    // calculate wind chill

                    if (ConvertUserWindToMS(WindAverage) < 1.5)
                    {
                        DoWindChill(OutdoorTemperature, timestamp);
                    }
                    else
                    {
                        // calculate wind chill from calibrated C temp and calibrated win in KPH
                        DoWindChill(ConvertTempCToUser(MeteoLib.WindChill(ConvertUserTempToC(OutdoorTemperature), ConvertUserWindToKPH(WindAverage))), timestamp);
                    }

                    DoApparentTemp(timestamp);

                    if (hasSolar)
                    {
                        if (historydata.uvVal == 255)
                        {
                            // ignore
                        }
                        else if (historydata.uvVal < 0)
                        {
                            DoUV(0, timestamp);
                        }
                        else if (historydata.uvVal > 16)
                        {
                            DoUV(16, timestamp);
                        }
                        else
                        {
                            DoUV(historydata.uvVal, timestamp);
                        }

                        if ((historydata.solarVal >= 0) && (historydata.solarVal <= 300000))
                        {
                            DoSolarRad((int)Math.Floor(historydata.solarVal * cumulus.LuxToWM2), timestamp);

                            // add in archive period worth of sunshine, if sunny
                            if ((SolarRad > CurrentSolarMax * cumulus.SunThreshold / 100) && (SolarRad >= cumulus.SolarMinimum))
                            {
                                SunshineHours = SunshineHours + (historydata.interval / 60.0);
                            }

                            LightValue = historydata.solarVal;
                        }
                    }
                }
                // add in 'following interval' minutes worth of wind speed to windrun
                cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.WindUnitText + " for " + historydata.followinginterval + " minutes = " +
                                   (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.followinginterval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.WindRunUnitText);

                WindRunToday += (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.followinginterval / 60.0);

                // update heating/cooling degree days
                UpdateDegreeDays(historydata.interval);

                // update dominant wind bearing
                CalculateDominantWindBearing(Bearing, WindAverage, historydata.interval);

                CheckForWindrunHighLow(timestamp);


                bw.ReportProgress((totalentries - datalist.Count) * 100 / totalentries, "processing");

                //UpdateDatabase(timestamp.ToUniversalTime(), historydata.interval, false);

                cumulus.DoLogFile(timestamp, false);
                if (cumulus.LogExtraSensors)
                {
                    cumulus.DoExtraLogFile(timestamp);
                }

                AddLastHourDataEntry(timestamp, Raincounter, OutdoorTemperature);
                AddGraphDataEntry(timestamp, Raincounter, RainToday, RainRate, OutdoorTemperature, OutdoorDewpoint, ApparentTemperature, WindChill, HeatIndex,
                                  IndoorTemperature, Pressure, WindAverage, RecentMaxGust, AvgBearing, Bearing, OutdoorHumidity, IndoorHumidity, SolarRad, CurrentSolarMax, UV);
                AddLast3HourDataEntry(timestamp, Pressure, OutdoorTemperature);
                AddRecentDataEntry(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing, OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex,
                                   OutdoorHumidity, Pressure, RainToday, SolarRad, UV, Raincounter);
                RemoveOldLHData(timestamp);
                RemoveOldL3HData(timestamp);
                RemoveOldGraphData(timestamp);
                DoTrendValues(timestamp);
                UpdatePressureTrendString();
                UpdateStatusPanel(timestamp);
                cumulus.AddToWebServiceLists(timestamp);
                datalist.RemoveAt(datalist.Count - 1);
            }
            cumulus.LogMessage("End processing history data");
        }
Esempio n. 4
0
        private void ProcessHistoryData(List <Observation> datalist)
        {
            var totalentries = datalist.Count;

            cumulus.LogMessage("Processing history data, number of entries = " + totalentries);
            cumulus.LogConsoleMessage(
                $"Processing history data for {totalentries} records. {DateTime.Now.ToLongTimeString()}");

            var rollHour         = Math.Abs(cumulus.GetHourInc());
            var luhour           = cumulus.LastUpdateTime.Hour;
            var rolloverdone     = luhour == rollHour;
            var midnightraindone = luhour == 0;

            var ticks = Environment.TickCount;

            foreach (var historydata in datalist)
            {
                var timestamp = historydata.Timestamp;

                cumulus.LogMessage("Processing data for " + timestamp);

                var h = timestamp.Hour;

                //  if outside rollover hour, rollover yet to be done
                if (h != rollHour)
                {
                    rolloverdone = false;
                }

                // In rollover hour and rollover not yet done
                if (h == rollHour && !rolloverdone)
                {
                    // do rollover
                    cumulus.LogMessage("Day rollover " + timestamp.ToShortTimeString());
                    DayReset(timestamp);

                    rolloverdone = true;
                }

                // Not in midnight hour, midnight rain yet to be done
                if (h != 0)
                {
                    midnightraindone = false;
                }

                // In midnight hour and midnight rain (and sun) not yet done
                if (h == 0 && !midnightraindone)
                {
                    ResetMidnightRain(timestamp);
                    ResetSunshineHours();
                    midnightraindone = true;
                }

                // Pressure =============================================================
                var alt      = AltitudeM(cumulus.Altitude);
                var seaLevel = GetSeaLevelPressure(alt, (double)historydata.StationPressure, (double)historydata.Temperature);
                DoPressure(ConvertPressMBToUser(seaLevel), timestamp);

                // Outdoor Humidity =====================================================
                DoOutdoorHumidity((int)historydata.Humidity, timestamp);

                // Wind =================================================================
                DoWind(ConvertWindMSToUser((double)historydata.WindGust), historydata.WindDirection,
                       ConvertWindMSToUser((double)historydata.WindAverage), timestamp);

                // Outdoor Temperature ==================================================
                DoOutdoorTemp(ConvertTempCToUser((double)historydata.Temperature), timestamp);
                // add in 'archivePeriod' minutes worth of temperature to the temp samples
                tempsamplestoday += historydata.ReportInterval;
                TempTotalToday   += OutdoorTemperature * historydata.ReportInterval;

                // update chill hours
                if (OutdoorTemperature < cumulus.ChillHourThreshold)
                {
                    // add 1 minute to chill hours
                    ChillHours += historydata.ReportInterval / 60.0;
                }

                double rainrate = (double)(ConvertRainMMToUser((double)historydata.Precipitation) *
                                           (60d / historydata.ReportInterval));

                var newRain = Raincounter + ConvertRainMMToUser((double)historydata.Precipitation);
                cumulus.LogMessage(
                    $"TempestDoRainHist: New Precip: {historydata.Precipitation}, Type: {historydata.PrecipType}, Rate: {rainrate}, LocalDayRain: {historydata.LocalDayRain}, LocalRainChecked: {historydata.LocalRainChecked}, FinalRainChecked: {historydata.FinalRainChecked}");

                DoRain(newRain, rainrate, timestamp);
                cumulus.LogMessage(
                    $"TempestDoRainHist: Total Precip for Day: {Raincounter}");

                OutdoorDewpoint =
                    ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature),
                                                         OutdoorHumidity));

                CheckForDewpointHighLow(timestamp);

                // calculate wind chill

                if (ConvertUserWindToMS(WindAverage) < 1.5)
                {
                    DoWindChill(OutdoorTemperature, timestamp);
                }
                else
                {
                    // calculate wind chill from calibrated C temp and calibrated win in KPH
                    DoWindChill(
                        ConvertTempCToUser(MeteoLib.WindChill(ConvertUserTempToC(OutdoorTemperature),
                                                              ConvertUserWindToKPH(WindAverage))), timestamp);
                }

                DoApparentTemp(timestamp);
                DoFeelsLike(timestamp);
                DoHumidex(timestamp);


                DoUV((double)historydata.UV, timestamp);

                DoSolarRad(historydata.SolarRadiation, timestamp);

                // add in archive period worth of sunshine, if sunny
                if (SolarRad > CurrentSolarMax * cumulus.SunThreshold / 100 &&
                    SolarRad >= cumulus.SolarMinimum)
                {
                    SunshineHours += historydata.ReportInterval / 60.0;
                }

                LightValue = historydata.Illuminance;


                // add in 'following interval' minutes worth of wind speed to windrun
                cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.Units.WindText + " for " + historydata.ReportInterval + " minutes = " +
                                   (WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.ReportInterval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.Units.WindRunText);

                WindRunToday += WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.ReportInterval / 60.0;

                // update heating/cooling degree days
                UpdateDegreeDays(historydata.ReportInterval);

                // update dominant wind bearing
                CalculateDominantWindBearing(Bearing, WindAverage, historydata.ReportInterval);

                CheckForWindrunHighLow(timestamp);

                bw?.ReportProgress((totalentries - datalist.Count) * 100 / totalentries, "processing");

                //UpdateDatabase(timestamp.ToUniversalTime(), historydata.interval, false);

                cumulus.DoLogFile(timestamp, false);
                if (cumulus.StationOptions.LogExtraSensors)
                {
                    cumulus.DoExtraLogFile(timestamp);
                }

                //AddRecentDataEntry(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing,
                //    OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex,
                //    OutdoorHumidity, Pressure, RainToday, SolarRad, UV, Raincounter, FeelsLike, Humidex);

                AddRecentDataWithAq(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing, OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex,
                                    OutdoorHumidity, Pressure, RainToday, SolarRad, UV, Raincounter, FeelsLike, Humidex, ApparentTemperature, IndoorTemperature, IndoorHumidity, CurrentSolarMax, RainRate);

                DoTrendValues(timestamp);
                UpdatePressureTrendString();
                UpdateStatusPanel(timestamp);
                cumulus.AddToWebServiceLists(timestamp);
            }

            ticks = Environment.TickCount - ticks;
            var rate = ((double)totalentries / ticks) * 1000;

            cumulus.LogMessage($"End processing history data. Rate: {rate:f2}/second");
            cumulus.LogConsoleMessage($"Completed processing history data. {DateTime.Now.ToLongTimeString()}, Rate: {rate:f2}/second");
        }
Esempio n. 5
0
        private void WeatherPacketReceived(WeatherPacket wp)
        {
            DateTime ts;

            if (wp != null)
            {
                switch (wp.MsgType)
                {
                case WeatherPacket.MessageType.Observation:
                    ts = wp.Observation.Timestamp;
                    var userTemp = ConvertTempCToUser(Convert.ToDouble(wp.Observation.Temperature));

                    DoOutdoorTemp(userTemp, ts);
                    DoWind(ConvertWindMSToUser((double)wp.Observation.WindGust),
                           wp.Observation.WindDirection,
                           ConvertWindMSToUser((double)wp.Observation.WindAverage),
                           ts);

                    var alt      = AltitudeM(cumulus.Altitude);
                    var seaLevel = GetSeaLevelPressure(alt, (double)wp.Observation.StationPressure,
                                                       (double)wp.Observation.Temperature);
                    DoPressure(ConvertPressMBToUser(seaLevel), ts);
                    cumulus.LogMessage(
                        $"TempestPressure: Station:{wp.Observation.StationPressure} mb, Sea Level:{seaLevel} mb, Altitude:{alt}");

                    DoSolarRad(wp.Observation.SolarRadiation, ts);
                    DoUV((double)wp.Observation.UV, ts);
                    double rainrate = (double)(ConvertRainMMToUser((double)wp.Observation.Precipitation) *
                                               (60d / wp.Observation.ReportInterval));

                    var newRain = Raincounter + ConvertRainMMToUser((double)wp.Observation.Precipitation);
                    cumulus.LogMessage(
                        $"TempestDoRain: New Precip: {wp.Observation.Precipitation}, Type: {wp.Observation.PrecipType}, Rate: {rainrate}");

                    DoRain(newRain, rainrate, ts);
                    cumulus.LogMessage(
                        $"TempestDoRain: Total Precip for Day: {Raincounter}");

                    DoOutdoorHumidity((int)wp.Observation.Humidity, ts);

                    OutdoorDewpoint =
                        ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature),
                                                             OutdoorHumidity));

                    CheckForDewpointHighLow(ts);

                    DoApparentTemp(ts);
                    DoFeelsLike(ts);
                    DoWindChill(userTemp, ts);
                    DoHumidex(ts);
                    DoPressTrend(null);
                    UpdateStatusPanel(ts);
                    UpdateMQTT();
                    DoForecast(string.Empty, false);

                    cumulus.BatteryLowAlarm.Triggered = wp.Observation.BatteryVoltage <= 2.355M;

                    break;

                case WeatherPacket.MessageType.RapidWind:
                    var rw = wp.RapidWind;
                    DoWind(ConvertWindMSToUser((double)rw.WindSpeed),
                           rw.WindDirection,
                           ConvertWindMSToUser((double)rw.WindSpeed),
                           rw.Timestamp);
                    UpdateStatusPanel(rw.Timestamp);

                    break;

                case WeatherPacket.MessageType.LightningStrike:
                    LightningTime     = wp.LightningStrike.Timestamp;
                    LightningDistance = ConvertKmtoUserUnits(wp.LightningStrike.Distance);
                    LightningStrikesToday++;
                    cumulus.LogMessage($"Lightning Detected: {wp.LightningStrike.Timestamp} - {wp.LightningStrike.Distance} km - {LightningStrikesToday} strikes today");
                    break;
                }
            }
        }
Esempio n. 6
0
        private int ws2300ReadHistoryRecord(int record, out int address, out double tempindoor, out double tempoutdoor, out double pressure, out int humindoor, out int humoutdoor,
                                            out double raincount, out double windspeed, out double winddir, out double dewpoint, out double windchill)
        {
            byte[] data    = new byte[20];
            byte[] command = new byte[25];

            int bytes = 10;
            int tempint;

            address = 0x6C6 + record * 19;
            cumulus.LogMessage("Reading history record " + record);
            if (ws2300ReadWithRetries(address, bytes, data, command) != bytes)
            {
                cumulus.LogMessage("Failed to read history record");
                tempindoor  = 0;
                tempoutdoor = 0;
                pressure    = 0;
                humindoor   = 0;
                humoutdoor  = 0;
                raincount   = 0;
                windspeed   = 0;
                winddir     = 0;
                dewpoint    = 0;
                windchill   = 0;
                return(-1000);
            }

            string msg = "History record read: ";

            for (int n = 0; n < bytes; n++)
            {
                msg += data[n].ToString("X2");
                msg += " ";
            }

            cumulus.LogMessage(msg);
            tempint = (data[4] << 12) + (data[3] << 4) + (data[2] >> 4);

            pressure = 1000 + (tempint % 10000) / 10.0;

            if (pressure >= 1502.2)
            {
                pressure = pressure - 1000;
            }

            pressure = ConvertPressMBToUser(pressure);

            humindoor = (int)((tempint - (tempint % 10000)) / 10000.0);

            humoutdoor = (data[5] >> 4) * 10 + (data[5] & 0xF);

            raincount = ConvertRainMMToUser(rainref + (((data[7] & 0xF) * 256 + data[6]) - raincountref) * 0.518);

            windspeed = (data[8] * 16 + (data[7] >> 4)) / 10.0;

            if (windspeed > 49.9)
            {
                // probably lost sensor contact
                windspeed = 0;
            }

            // need wind in kph for chill calc
            double windkmh = 3.6 * windspeed;

            tempint     = ((data[2] & 0xF) << 16) + (data[1] << 8) + data[0];
            tempindoor  = ConvertTempCToUser((tempint % 1000) / 10.0f - 30.0);
            tempoutdoor = (tempint - (tempint % 1000)) / 10000.0f - 30.0;

            windchill = ConvertTempCToUser(MeteoLib.WindChill(tempoutdoor, windkmh));
            dewpoint  = ConvertTempCToUser(MeteoLib.DewPoint(tempoutdoor, humoutdoor));

            tempoutdoor = ConvertTempCToUser(tempoutdoor);

            windspeed = ConvertWindMSToUser(windspeed);
            winddir   = (data[9] & 0xF) * 22.5;


            return((++record) % 0xAF);
        }
Esempio n. 7
0
        private void processHistoryData()
        {
            // history data is alread in correct units
            int totalentries = datalist.Count;
            int rollHour     = Math.Abs(cumulus.GetHourInc());
            int luhour       = cumulus.LastUpdateTime.Hour;

            bool rolloverdone = luhour == rollHour;

            bool midnightraindone = luhour == 0;

            double prevraintotal = -1;
            double raindiff, rainrate;

            double pressureoffset = ConvertPressMBToUser(ws2300PressureOffset());

            while (datalist.Count > 0)
            {
                historyData historydata = datalist[datalist.Count - 1];

                DateTime timestamp = historydata.timestamp;

                cumulus.LogMessage("Processing data for " + timestamp);
                // Check for rollover

                int h = timestamp.Hour;

                if (h != rollHour)
                {
                    rolloverdone = false;
                }

                if ((h == rollHour) && !rolloverdone)
                {
                    // do rollover
                    cumulus.LogMessage("WS2300: Day rollover " + timestamp);
                    DayReset(timestamp);

                    rolloverdone = true;
                }

                // handle rain since midnight reset
                if (h != 0)
                {
                    midnightraindone = false;
                }

                if ((h == 0) && !midnightraindone)
                {
                    ResetMidnightRain(timestamp);
                    ResetSunshineHours();
                    midnightraindone = true;
                }

                // Humidity ====================================================================
                if ((historydata.inHum > 0) && (historydata.inHum <= 100))
                {
                    DoIndoorHumidity(historydata.inHum);
                }
                if ((historydata.outHum > 0) && (historydata.outHum <= 100))
                {
                    DoOutdoorHumidity(historydata.outHum, timestamp);
                }

                // Wind ========================================================================
                if (historydata.windSpeed < cumulus.LCMaxWind)
                {
                    DoWind(historydata.windGust, historydata.windBearing, historydata.windSpeed, timestamp);
                }

                // Temperature ==================================================================
                if ((historydata.outTemp > -50) && (historydata.outTemp < 50))
                {
                    DoOutdoorTemp(historydata.outTemp, timestamp);

                    tempsamplestoday = tempsamplestoday + historydata.interval;
                    TempTotalToday   = TempTotalToday + (OutdoorTemperature * historydata.interval);

                    if (OutdoorTemperature < cumulus.ChillHourThreshold)
                    // add 1 minute to chill hours
                    {
                        ChillHours += (historydata.interval / 60.0);
                    }
                }

                if ((historydata.inTemp > -50) && (historydata.inTemp < 50))
                {
                    DoIndoorTemp(historydata.inTemp);
                }

                // Rain ==========================================================================
                if (prevraintotal < 0)
                {
                    raindiff = 0;
                }
                else
                {
                    raindiff = historydata.rainTotal - prevraintotal;
                }

                if (historydata.interval > 0)
                {
                    rainrate = (raindiff) * (60 / historydata.interval);
                }
                else
                {
                    rainrate = 0;
                }

                cumulus.LogMessage("WS2300: History rain total = " + historydata.rainTotal);

                DoRain(historydata.rainTotal, rainrate, timestamp);

                prevraintotal = historydata.rainTotal;

                // Dewpoint ====================================================================
                if (cumulus.CalculatedDP)
                {
                    double tempC = ConvertUserTempToC(OutdoorTemperature);
                    DoOutdoorDewpoint(ConvertTempCToUser(MeteoLib.DewPoint(tempC, OutdoorHumidity)), timestamp);
                    CheckForDewpointHighLow(timestamp);
                }
                else
                {
                    if (historydata.dewpoint < ConvertUserTempToC(60))
                    {
                        DoOutdoorDewpoint(CalibrateTemp(historydata.dewpoint), timestamp);
                    }
                }

                // Windchill ==================================================================
                if (cumulus.CalculatedWC)
                {
                    if (ConvertUserWindToMS(WindAverage) < 1.5)
                    {
                        DoWindChill(OutdoorTemperature, timestamp);
                    }
                    else
                    {
                        // calculate wind chill from calibrated C temp and calibrated win in KPH
                        DoWindChill(ConvertTempCToUser(MeteoLib.WindChill(ConvertUserTempToC(OutdoorTemperature), ConvertUserWindToKPH(WindAverage))), timestamp);
                    }
                }
                else
                {
                    if (historydata.windchill < ConvertTempCToUser(60))
                    {
                        DoWindChill(historydata.windchill, timestamp);
                    }
                }

                // Wind run ======================================================================
                cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.WindUnitText + " for " + historydata.interval + " minutes = " +
                                   (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.interval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.WindRunUnitText);

                WindRunToday += (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.interval / 60.0);

                CheckForWindrunHighLow(timestamp);

                // Pressure ======================================================================
                double slpress = historydata.pressure + pressureoffset;

                if ((slpress > ConvertPressMBToUser(900)) && (slpress < ConvertPressMBToUser(1200)))
                {
                    DoPressure(slpress, timestamp);
                }

                // update heating/cooling degree days
                UpdateDegreeDays(historydata.interval);

                DoApparentTemp(timestamp);

                CalculateDominantWindBearing(Bearing, WindAverage, historydata.interval);

                bw.ReportProgress((totalentries - datalist.Count) * 100 / totalentries, "processing");

                //UpdateDatabase(timestamp.ToUniversalTime(), historydata.interval, false);

                cumulus.DoLogFile(timestamp, false);
                if (cumulus.LogExtraSensors)
                {
                    cumulus.DoExtraLogFile(timestamp);
                }

                AddLastHourDataEntry(timestamp, Raincounter, OutdoorTemperature);
                AddGraphDataEntry(timestamp, Raincounter, RainToday, RainRate, OutdoorTemperature, OutdoorDewpoint, ApparentTemperature, WindChill, HeatIndex, IndoorTemperature, Pressure, WindAverage, RecentMaxGust, AvgBearing, Bearing, OutdoorHumidity, IndoorHumidity, SolarRad, CurrentSolarMax, UV);
                AddLast3HourDataEntry(timestamp, Pressure, OutdoorTemperature);
                AddRecentDataEntry(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing, OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex, OutdoorHumidity,
                                   Pressure, RainToday, SolarRad, UV, Raincounter);
                RemoveOldLHData(timestamp);
                RemoveOldL3HData(timestamp);
                RemoveOldGraphData(timestamp);
                DoTrendValues(timestamp);
                UpdatePressureTrendString();
                UpdateStatusPanel(timestamp);
                cumulus.AddToWebServiceLists(timestamp);

                datalist.RemoveAt(datalist.Count - 1);
            }
        }