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; }
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; }
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; }
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; }
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; }