Пример #1
0
static int daemonStationLoopComplete (void)
{
    float           tempf, sampleRain, sampleET;

    if (!wviewdWork.runningFlag)
    {
        return OK;
    }

    // Adjust for calibrations:
    // DO NOT calibrate pressure here:

    wviewdWork.loopPkt.inTemp           *= wviewdWork.calMInTemp;
    wviewdWork.loopPkt.inTemp           += wviewdWork.calCInTemp;

    wviewdWork.loopPkt.outTemp          *= wviewdWork.calMOutTemp;
    wviewdWork.loopPkt.outTemp          += wviewdWork.calCOutTemp;

    wviewdWork.loopPkt.inHumidity       *= wviewdWork.calMInHumidity;
    wviewdWork.loopPkt.inHumidity       += wviewdWork.calCInHumidity;

    wviewdWork.loopPkt.outHumidity      *= wviewdWork.calMOutHumidity;
    wviewdWork.loopPkt.outHumidity      += wviewdWork.calCOutHumidity;

    wviewdWork.loopPkt.windSpeed        *= wviewdWork.calMWindSpeed;
    wviewdWork.loopPkt.windSpeed        += wviewdWork.calCWindSpeed;

    wviewdWork.loopPkt.windDir          *= wviewdWork.calMWindDir;
    wviewdWork.loopPkt.windDir          += wviewdWork.calCWindDir;
    wviewdWork.loopPkt.windDir          %= 360;

    wviewdWork.loopPkt.sampleRain       *= wviewdWork.calMRain;
    wviewdWork.loopPkt.sampleRain       += wviewdWork.calCRain;

    wviewdWork.loopPkt.rainRate         *= wviewdWork.calMRainRate;
    wviewdWork.loopPkt.rainRate         += wviewdWork.calCRainRate;

    // now calculate a few after all calibrations:
    wviewdWork.loopPkt.dewpoint = wvutilsCalculateDewpoint(wviewdWork.loopPkt.outTemp,
                                                           (float)wviewdWork.loopPkt.outHumidity);
    wviewdWork.loopPkt.windchill = wvutilsCalculateWindChill(wviewdWork.loopPkt.outTemp,
                                                             (float)wviewdWork.loopPkt.windSpeed);
    wviewdWork.loopPkt.heatindex = wvutilsCalculateHeatIndex(wviewdWork.loopPkt.outTemp,
                                                             (float)wviewdWork.loopPkt.outHumidity);

    // store the results:
    computedDataStoreSample (&wviewdWork);

    // lose any trace amounts to avoid rounding up by sprintf:
    sampleRain = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_INTERVAL][SENSOR_RAIN]);
    sampleRain *= 100;
    sampleRain = floorf (sampleRain);
    sampleRain /= 100;
    sampleET = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_INTERVAL][SENSOR_ET]);
    sampleET *= 1000;
    sampleET = floorf (sampleET);
    sampleET /= 1000;

    // do some post-processing on the LOOP data:
    tempf = stormRainGet();
    if (tempf > 0)
        tempf += sampleRain;
    wviewdWork.loopPkt.stormRain        = tempf;
    wviewdWork.loopPkt.stormStart       = stormRainGetStartTimeT();

    tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_DAY][SENSOR_RAIN]);
    tempf += sampleRain;
    wviewdWork.loopPkt.dayRain          = tempf;

    tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_MONTH][SENSOR_RAIN]);
    tempf += sampleRain;
    wviewdWork.loopPkt.monthRain        = tempf;

    tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_YEAR][SENSOR_RAIN]);
    tempf += sampleRain;
    wviewdWork.loopPkt.yearRain         = tempf;

    if (sampleET > ARCHIVE_VALUE_NULL)
    {
        tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_DAY][SENSOR_ET]);
        tempf += sampleET;
        wviewdWork.loopPkt.dayET            = tempf;
    
        tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_MONTH][SENSOR_ET]);
        tempf += sampleET;
        wviewdWork.loopPkt.monthET          = tempf;
    
        tempf = sensorGetCumulative(&wviewdWork.sensors.sensor[STF_YEAR][SENSOR_ET]);
        tempf += sampleET;
        wviewdWork.loopPkt.yearET           = tempf;
    }

    wviewdWork.loopPkt.yearRainMonth    = wviewdWork.stationRainSeasonStart;

    statusIncrementStat(WVIEW_STATS_LOOP_PKTS_RX);
    return OK;
}
Пример #2
0
ARCHIVE_PKT *computedDataGenerateArchive (WVIEWD_WORK *work)
{
    WV_SENSOR       *sample = work->sensors.sensor[STF_INTERVAL];
    time_t          nowtime = time (NULL);
    int             tempInt;
    float           tempfloat, tempfloat1;
    struct tm       bknTime;
    Data_Indices    index;

    // create the time_t time for the record:
    localtime_r (&nowtime, &bknTime);
    bknTime.tm_sec  = 0;
    ArcRecStore.dateTime = (int32_t)mktime(&bknTime);

    ArcRecStore.usUnits  = 1;
    ArcRecStore.interval = work->archiveInterval;

    // Set all values to NULL by default:
    for (index = DATA_INDEX_barometer; index < DATA_INDEX_MAX; index ++)
    {
        ArcRecStore.value[index] = ARCHIVE_VALUE_NULL;
    }

    // have we received any LOOP updates this interval?
    if (sensorGetSamples(&sample[SENSOR_OUTTEMP]) == 0)
    {
        // we have not - squawk about it and exit
        radMsgLog (PRI_MEDIUM, "computedDataGenerateArchive: no samples for this interval!");
        return NULL;
    }

    // Set the values we can:
    ArcRecStore.value[DATA_INDEX_outTemp]        = (float)sensorGetAvg (&sample[SENSOR_OUTTEMP]);
    ArcRecStore.value[DATA_INDEX_rain]           = (float)sensorGetCumulative (&sample[SENSOR_RAIN]);
    ArcRecStore.value[DATA_INDEX_rainRate]       = (float)sensorGetHigh (&sample[SENSOR_RAINRATE]);
    ArcRecStore.value[DATA_INDEX_barometer]      = (float)sensorGetAvg (&sample[SENSOR_BP]);
    ArcRecStore.value[DATA_INDEX_pressure]       = 
        wvutilsConvertSLPToSP((float)ArcRecStore.value[DATA_INDEX_barometer],
                              (float)ArcRecStore.value[DATA_INDEX_outTemp],
                              (float)work->elevation);
    ArcRecStore.value[DATA_INDEX_altimeter]      = 
        wvutilsConvertSPToAltimeter((float)ArcRecStore.value[DATA_INDEX_pressure],
                                    (float)work->elevation);
    ArcRecStore.value[DATA_INDEX_inTemp]         = (float)sensorGetAvg (&sample[SENSOR_INTEMP]);
    ArcRecStore.value[DATA_INDEX_inHumidity]     = (float)sensorGetAvg (&sample[SENSOR_INHUMID]);
    ArcRecStore.value[DATA_INDEX_outHumidity]    = (float)sensorGetAvg (&sample[SENSOR_OUTHUMID]);
    ArcRecStore.value[DATA_INDEX_windSpeed]      = (float)sensorGetAvg (&sample[SENSOR_WSPEED]);
    if (sensorGetHigh (&sample[SENSOR_WGUST]) >= 0)
    {
        ArcRecStore.value[DATA_INDEX_windGust]   = (float)sensorGetHigh (&sample[SENSOR_WGUST]);
    }
    else
    {
        ArcRecStore.value[DATA_INDEX_windGust]   = 0;
    }

    // save the high wind speed in the loop packet
    work->loopPkt.windGust = (uint16_t)ArcRecStore.value[DATA_INDEX_windGust];

    ArcRecStore.value[DATA_INDEX_dewpoint]       =
        wvutilsCalculateDewpoint ((float)ArcRecStore.value[DATA_INDEX_outTemp],
                                  (float)ArcRecStore.value[DATA_INDEX_outHumidity]);
    ArcRecStore.value[DATA_INDEX_windchill]      =
        wvutilsCalculateWindChill ((float)ArcRecStore.value[DATA_INDEX_outTemp],
                                   (float)ArcRecStore.value[DATA_INDEX_windSpeed]);
    ArcRecStore.value[DATA_INDEX_heatindex]      =
        wvutilsCalculateHeatIndex ((float)ArcRecStore.value[DATA_INDEX_outTemp],
                                   (float)ArcRecStore.value[DATA_INDEX_outHumidity]);

    if (ArcRecStore.value[DATA_INDEX_windSpeed] > 0 || 
        ArcRecStore.value[DATA_INDEX_windGust] > 0)
    {
        ArcRecStore.value[DATA_INDEX_windDir]        = (float)windAverageCompute(&work->sensors.wind[STF_INTERVAL]);
        ArcRecStore.value[DATA_INDEX_windGustDir]    = (float)sensorGetWhenHigh(&sample[SENSOR_WGUST]);
    }

    // These are conditional based on loop data being populated:
    if (work->loopPkt.radiation != 0xFFFF)
        ArcRecStore.value[DATA_INDEX_radiation]      = (float)sensorGetAvg (&sample[SENSOR_SOLRAD]);
    if (work->loopPkt.UV != 0xFFFF)
        ArcRecStore.value[DATA_INDEX_UV]             = (float)sensorGetAvg (&sample[SENSOR_UV]);
    if (work->loopPkt.sampleET != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_ET]             = (float)sensorGetCumulative (&sample[SENSOR_ET]);
    if (work->loopPkt.wxt510Hail != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_hail]           = (float)sensorGetCumulative (&sample[SENSOR_HAIL]);
    if (work->loopPkt.wxt510Hailrate != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_hailrate]       = (float)sensorGetHigh (&sample[SENSOR_HAILRATE]);


    // Get a few directly from the last LOOP_PKT:
    if (work->loopPkt.rxCheckPercent != 0xFFFF)
        ArcRecStore.value[DATA_INDEX_rxCheckPercent] = (float)work->loopPkt.rxCheckPercent;
    if (work->loopPkt.wxt510HeatingTemp != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_heatingTemp]    = (float)work->loopPkt.wxt510HeatingTemp;
    if (work->loopPkt.wxt510HeatingVoltage != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_heatingVoltage] = (float)work->loopPkt.wxt510HeatingVoltage;
    if (work->loopPkt.wxt510SupplyVoltage != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_supplyVoltage]  = (float)work->loopPkt.wxt510SupplyVoltage;
    if (work->loopPkt.wxt510ReferenceVoltage != ARCHIVE_VALUE_NULL)
        ArcRecStore.value[DATA_INDEX_referenceVoltage] = (float)work->loopPkt.wxt510ReferenceVoltage;
    if (work->loopPkt.wmr918WindBatteryStatus != 0xFF)
        ArcRecStore.value[DATA_INDEX_windBatteryStatus] = (float)work->loopPkt.wmr918WindBatteryStatus;
    if (work->loopPkt.wmr918RainBatteryStatus != 0xFF)
        ArcRecStore.value[DATA_INDEX_rainBatteryStatus] = (float)work->loopPkt.wmr918RainBatteryStatus;
    if (work->loopPkt.wmr918OutTempBatteryStatus != 0xFF)
        ArcRecStore.value[DATA_INDEX_outTempBatteryStatus] = (float)work->loopPkt.wmr918OutTempBatteryStatus;
    if (work->loopPkt.wmr918InTempBatteryStatus != 0xFF)
        ArcRecStore.value[DATA_INDEX_inTempBatteryStatus] = (float)work->loopPkt.wmr918InTempBatteryStatus;

    return &ArcRecStore;
}