예제 #1
0
파일: wmr918protocol.c 프로젝트: breu/wview
static void storeLoopPkt (WVIEWD_WORK *work, LOOP_PKT *dest, WMR918_DATA *src)
{
    float               tempfloat;
    WMR918_IF_DATA*     ifWorkData = (WMR918_IF_DATA*)work->stationData;
    time_t              nowTime = time(NULL);

    // Clear optional data:
    stationClearLoopData(work);


    // WMR918 produces station pressure
    if (10 < src->pressure && src->pressure < 50)
    {
        dest->stationPressure               = src->pressure;

        // Apply calibration here so the computed values reflect it:
        dest->stationPressure *= work->calMPressure;
        dest->stationPressure += work->calCPressure;

        if (-150 < src->outTemp && src->outTemp < 150)
        {
            // compute sea-level pressure (BP)
            dest->barometer                 = wvutilsConvertSPToSLP (dest->stationPressure,
                                                                     src->outTemp,
                                                                     (float)ifWorkData->elevation);
        }

        // calculate altimeter
        dest->altimeter                     = wvutilsConvertSPToAltimeter (dest->stationPressure,
                                                                         (float)ifWorkData->elevation);
    }

    if (-150 < src->outTemp && src->outTemp < 150)
        dest->outTemp                       = src->outTemp;

    if (0 <= src->outHumidity && src->outHumidity <= 100)
    {
        tempfloat = src->outHumidity;
        tempfloat += 0.5;
        dest->outHumidity                   = (USHORT)tempfloat;
    }

    if (0 <= src->windSpeed && src->windSpeed <= 250)
    {
        tempfloat = src->windSpeed;
        tempfloat += 0.5;
        dest->windSpeed                     = (USHORT)tempfloat;
    }

    if (0 <= src->windDir && src->windDir <= 360)
    {
        tempfloat = src->windDir;
        tempfloat += 0.5;
        dest->windDir                       = (USHORT)tempfloat;
    }

    if (0 <= src->maxWindSpeed && src->maxWindSpeed <= 250)
    {
        tempfloat = src->maxWindSpeed;
        tempfloat += 0.5;
        dest->windGust                      = (USHORT)tempfloat;
    }

    if (0 <= src->maxWindDir && src->maxWindDir <= 360)
    {
        tempfloat = src->maxWindDir;
        tempfloat += 0.5;
        dest->windGustDir                   = (USHORT)tempfloat;
    }

    if (0 <= src->rain)
    {
        if (!work->runningFlag)
        {
            // just starting, so start with whatever the station reports:
            ifWorkData->totalRain = src->rain;
            dest->sampleRain = 0;
        }
        else
        {
            // process the rain accumulator
            if (src->rain - ifWorkData->totalRain >= 0)
            {
                dest->sampleRain = src->rain - ifWorkData->totalRain;
                ifWorkData->totalRain = src->rain;
            }
            else
            {
                // we had a counter reset...
                dest->sampleRain = src->rain;
                ifWorkData->totalRain = src->rain;
            }
        }

        if (dest->sampleRain > 2)
        {
            // Not possible, filter it out:
            dest->sampleRain = 0;
        }

        // Compute rain rate - the WMR918 rain rate is poor...
        // Update the rain accumulator:
        sensorAccumAddSample (ifWorkData->rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate                      = sensorAccumGetTotal (ifWorkData->rainRateAccumulator);
        dest->rainRate                      *= (60/WMR918_RAIN_RATE_PERIOD);
    }
    else
    {
        dest->sampleRain = 0;
        sensorAccumAddSample (ifWorkData->rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate                      = sensorAccumGetTotal (ifWorkData->rainRateAccumulator);
        dest->rainRate                      *= (60/WMR918_RAIN_RATE_PERIOD);
    }        

    dest->inTemp                        = src->inTemp;
    tempfloat = src->inHumidity;
    tempfloat += 0.5;
    dest->inHumidity                    = (USHORT)tempfloat;

    dest->extraTemp1                    = (float)src->extraTemp[0];
    tempfloat = src->extraHumidity[0];
    tempfloat += 0.5;
    dest->extraHumid1                   = (USHORT)tempfloat;

    dest->extraTemp2                    = (float)src->extraTemp[1];
    tempfloat = src->extraHumidity[1];
    tempfloat += 0.5;
    dest->extraHumid2                   = (USHORT)tempfloat;

    dest->extraTemp3                    = (float)src->extraTemp[2];

    // WMR918 specific:
    tempfloat = src->extraHumidity[2];
    tempfloat += 0.5;
    dest->wmr918Humid3                  = (USHORT)tempfloat;

    dest->wmr918Pool                    = src->pool;

    dest->wmr918WindBatteryStatus       = src->windBatteryStatus;
    dest->wmr918RainBatteryStatus       = src->rainBatteryStatus;
    dest->wmr918OutTempBatteryStatus    = src->outTempBatteryStatus;
    dest->wmr918InTempBatteryStatus     = src->inTempBatteryStatus;
    dest->wmr918poolTempBatteryStatus   = src->poolTempBatteryStatus;
    dest->wmr918extra1BatteryStatus     = src->extraBatteryStatus[0];
    dest->wmr918extra2BatteryStatus     = src->extraBatteryStatus[1];
    dest->wmr918extra3BatteryStatus     = src->extraBatteryStatus[2];
    dest->wmr918Tendency                = src->tendency;

    return;
}
예제 #2
0
static void storeLoopPkt (WVIEWD_WORK* work, LOOP_PKT *dest, TWI_DATA *src)
{
    float           tempfloat;
    static time_t   lastTempUpdate;
    time_t          nowTime = time(NULL);

    // Clear optional data:
    stationClearLoopData(work);

    // Pressure:
    if ((10 < src->bp && src->bp < 50) &&
        (-150 < src->outTemp && src->outTemp < 200))
    {
        if ((time(NULL) - lastTempUpdate) >= (twiWorkData.archiveInterval * 60))
        {
            // Add for the 12-hour temp average sample:
            // mimic an archive interval:
            sensorAccumAddSample(twi12HourTempAvg, time(NULL), src->outTemp);
            lastTempUpdate = time(NULL);
        }

        // TWI produces sea level pressure (SLP):
        dest->barometer = src->bp;

        // Apply calibration here so the computed values reflect it:
        dest->barometer *= work->calMBarometer;
        dest->barometer += work->calCBarometer;

        // calculate station pressure:
        dest->stationPressure = twiConvertSLPToSP(dest->barometer, 
                                                 sensorAccumGetAverage(twi12HourTempAvg), 
                                                 (float)twiWorkData.elevation);

        // now calculate altimeter:
        dest->altimeter = wvutilsConvertSPToAltimeter(dest->stationPressure,
                                                      (float)twiWorkData.elevation);
    }


    if (-150 < src->inTemp && src->inTemp < 200)
    {
        dest->inTemp                        = src->inTemp;
    }

    if (-150 < src->outTemp && src->outTemp < 200)
    {
        dest->outTemp                       = src->outTemp;
    }

    if (0 <= src->humidity && src->humidity <= 100)
    {
        dest->outHumidity                   = (uint16_t)src->humidity;
        dest->inHumidity                    = (uint16_t)src->humidity;
    }

    if (0 <= src->windSpeed && src->windSpeed <= 250)
    {
        tempfloat = src->windSpeed;
        tempfloat += 0.5;
        dest->windSpeed                     = (uint16_t)tempfloat;
        dest->windGust                      = (uint16_t)tempfloat;
    }

    if (0 <= src->windDir && src->windDir < 360)
    {
        tempfloat = src->windDir;
        tempfloat += 0.5;
        dest->windDir                       = (uint16_t)tempfloat;
        dest->windGustDir                   = (uint16_t)tempfloat;
    }

    dest->rainRate                          = src->rainrate;

    // process the rain accumulator:
    if (0 <= src->dayrain)
    {
        if (! work->runningFlag)
        {
            // just starting, so start with whatever the station reports:
            twiWorkData.totalRain = src->dayrain;
            dest->sampleRain = 0;
        }
        else
        {
            // process the rain accumulator
            if (src->dayrain - twiWorkData.totalRain >= 0)
            {
                dest->sampleRain = src->dayrain - twiWorkData.totalRain;
                twiWorkData.totalRain = src->dayrain;
            }
            else
            {
                // we had a counter reset...
                dest->sampleRain = src->dayrain;
                twiWorkData.totalRain = src->dayrain;
            }
        }

        if (dest->sampleRain > 2)
        {
            // Not possible, filter it out:
            dest->sampleRain = 0;
        }

        // Update the rain accumulator:
        sensorAccumAddSample (twiWorkData.rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate    = sensorAccumGetTotal (twiWorkData.rainRateAccumulator);
        dest->rainRate   *= (60/TWI_RAIN_RATE_PERIOD);
    }
    else
    {
        dest->sampleRain = 0;
        sensorAccumAddSample (twiWorkData.rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate   = sensorAccumGetTotal (twiWorkData.rainRateAccumulator);
        dest->rainRate   *= (60/TWI_RAIN_RATE_PERIOD);
    }

    return;
}
예제 #3
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;
}
예제 #4
0
파일: simulator.c 프로젝트: oldelvet/wview
static void storeLoopPkt (WVIEWD_WORK *work, LOOP_PKT *dest)
{
    float       tempfloat;

    // Clear optional data:
    stationClearLoopData(work);


    // vary BP from 29.75 to 30.25
    tempfloat = 30.00;
    tempfloat += sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 0.25;
    // Sim "produces" sea level pressure (SLP)
    dest->barometer = tempfloat;

    // vary TEMP from 60 to 80
    tempfloat = 70;
    tempfloat += sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 10.0;
    dest->outTemp = tempfloat;

    // Apply calibration here so the computed values reflect it:
    dest->barometer *= work->calMBarometer;
    dest->barometer += work->calCBarometer;

    // calculate station pressure by giving a negative elevation 
    dest->stationPressure = wvutilsConvertSPToSLP(dest->barometer, 
                                                dest->outTemp,
                                                (float)(-simWorkData.elevation));

    // calculate altimeter
    dest->altimeter = wvutilsConvertSPToAltimeter(dest->stationPressure,
                                                (float)simWorkData.elevation);

    // vary HUMIDITY from 60 to 80
    tempfloat = 70.0;
    tempfloat -= sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 10.0;
    dest->outHumidity = (uint16_t)tempfloat;

    // vary WINDSPD from 5 to 15
    tempfloat = 10;
    tempfloat += sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 5.0;
    dest->windSpeed = (uint16_t)tempfloat;

    // vary WINDDIR from 0 to 90
    tempfloat = 0;
    tempfloat += fabsf(sin((float)DataGenerator*RAD/PERIOD_FACTOR)) * 90.0;
    dest->windDir = (uint16_t)tempfloat;

    // vary MAXWIND from 15 to 25
    tempfloat = 20;
    tempfloat += sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 5.0;
    dest->windGust = (uint16_t)tempfloat;

    // vary MAXWINDDIR from 0 to 90
    tempfloat = 45;
    tempfloat += sin((float)DataGenerator*RAD/PERIOD_FACTOR) * 45.0;
    dest->windGustDir = (uint16_t)tempfloat;

    // vary RAINRATE from 0.00 to 4.8
    tempfloat = 0;
    tempfloat += fabsf(sin((float)DataGenerator*RAD/PERIOD_FACTOR)) * 4.8;
    dest->rainRate = tempfloat;

    // vary RAIN from 0.00 to 0.02
    tempfloat = 0;
    tempfloat += fabsf(sin((float)DataGenerator*RAD/PERIOD_FACTOR)) * 0.02;
    dest->sampleRain = tempfloat;

    // bump our data generator index
    DataGenerator ++;
    DataGenerator %= (360*PERIOD_FACTOR);
    
    return;
}
예제 #5
0
static void storeLoopPkt (WVIEWD_WORK *work, LOOP_PKT *dest, WH1080_DATA *src)
{
    float               tempfloat;
    WH1080_IF_DATA*     ifWorkData = (WH1080_IF_DATA*)work->stationData;
    time_t              nowTime = time(NULL);

    // Clear optional data:
    stationClearLoopData(work);

    if ((10 < src->pressure && src->pressure < 50) &&
        (-150 < src->outtemp && src->outtemp < 150))
    {
        // WH1080 produces station pressure
        dest->stationPressure               = src->pressure;
    
        // Apply calibration here so the computed values reflect it:
        dest->stationPressure *= work->calMPressure;
        dest->stationPressure += work->calCPressure;
    
        // compute sea-level pressure (BP)
        tempfloat = wvutilsConvertSPToSLP(dest->stationPressure,
                                          src->outtemp,
                                          (float)ifWorkData->elevation);
        dest->barometer                     = tempfloat;
    
        // calculate altimeter
        tempfloat = wvutilsConvertSPToAltimeter(dest->stationPressure,
                                                (float)ifWorkData->elevation);
        dest->altimeter                     = tempfloat;
    }

    if (-150 < src->outtemp && src->outtemp < 150)
    {
        dest->outTemp  = src->outtemp;
    }

    if (0 <= src->outhumidity && src->outhumidity <= 100)
    {
        tempfloat = src->outhumidity;
        tempfloat += 0.5;
        dest->outHumidity  = (uint16_t)tempfloat;
    }

    if (0 <= src->windAvgSpeed && src->windAvgSpeed <= 250)
    {
        tempfloat = src->windAvgSpeed;
        dest->windSpeedF  = tempfloat;
    }

    if (0 <= src->windDir && src->windDir <= 360)
    {
        tempfloat = src->windDir;
        tempfloat += 0.5;
        dest->windDir        = (uint16_t)tempfloat;
        dest->windGustDir    = (uint16_t)tempfloat;
    }

    if (0 <= src->windGustSpeed && src->windGustSpeed <= 250)
    {
        tempfloat = src->windGustSpeed;
        dest->windGustF      = tempfloat;
    }

    if (0 <= src->rain)
    {
        if (!work->runningFlag)
        {
            // just starting, so start with whatever the station reports:
            ifWorkData->totalRain = src->rain;
            dest->sampleRain = 0;
        }
        else
        {
            // process the rain accumulator
            if (src->rain - ifWorkData->totalRain >= 0)
            {
                dest->sampleRain = src->rain - ifWorkData->totalRain;
                ifWorkData->totalRain = src->rain;
            }
            else
            {
                // we had a counter reset...
                dest->sampleRain = src->rain;
                dest->sampleRain += (WH1080_RAIN_MAX - ifWorkData->totalRain);
                ifWorkData->totalRain = src->rain;
            }
        }

        if (dest->sampleRain > 2)
        {
            // Not possible, filter it out:
            dest->sampleRain = 0;
        }

        // Update the rain accumulator:
        sensorAccumAddSample (ifWorkData->rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate    = sensorAccumGetTotal (ifWorkData->rainRateAccumulator);
        dest->rainRate   *= (60/WH1080_RAIN_RATE_PERIOD);
    }
    else
    {
        dest->sampleRain = 0;
        sensorAccumAddSample (ifWorkData->rainRateAccumulator, nowTime, dest->sampleRain);
        dest->rainRate                      = sensorAccumGetTotal (ifWorkData->rainRateAccumulator);
        dest->rainRate                      *= (60/WH1080_RAIN_RATE_PERIOD);
    }

    dest->inTemp                        = src->intemp;
    tempfloat = src->inhumidity;
    tempfloat += 0.5;
    dest->inHumidity                    = (uint16_t)tempfloat;

    return;
}