Ejemplo n.º 1
0
float wvutilsCalculateAirDensity (float tempF, float bp, float dp)
{
    float       tempC = wvutilsConvertFToC (tempF);
    float       bpMB = wvutilsConvertINHGToHPA (bp);
    float       dewpoint = wvutilsConvertFToC (dp);
    float       emb = getVaporPressure (dewpoint);
    float       density = calcDensity (bpMB, emb, tempC);

    return density;
}
Ejemplo n.º 2
0
// Calculate the apparent temperature:
// Australian Bureau of Meteorology http://reg.bom.gov.au/info/thermal_stress/#atapproximation [^]
// Robert G. Steadman. 1994: Norms of apparent temperature in Australia.
float wvutilsCalculateApparentTemp(float temp, float windspeed, float humidity)
{
    double AT,Ta,e,ws;
    double result;
    
    Ta = wvutilsConvertFToC(temp);
    e = humidity / 100.0 * 6.105 * exp(17.27 * Ta/( 237.7 + Ta));
    ws = wvutilsConvertMPHToMPS(windspeed);
    AT = Ta + 0.33 * e - 0.70 * ws - 4.00;
    result = wvutilsConvertCToF(AT);
    
    return (float)result;
}
Ejemplo n.º 3
0
//  Calculate the "e ^ (-mgh/RT)" term for pressure conversions:
static double calcPressureTerm(float tempF, float elevationFT)
{
    double      exponent;
    double      elevMeters = (double)wvutilsConvertFeetToMeters(elevationFT);
    double      tempKelvin = (double)wvutilsConvertFToC(tempF) + 273.15;

    // e ^ -elevMeters/(tempK * 29.263)
    exponent = (-elevMeters);

    // degrees Kelvin (T)
    exponent /= (tempKelvin * 29.263);

    // e ^ (-mgh/RT)
    exponent = exp(exponent);

    return exponent;
}
Ejemplo n.º 4
0
// Calculate the wet bulb temperature:
// Based on NOAA Java Script http://www.srh.noaa.gov/epz/?n=wxcalc_rh
float wvutilsCalculateWetBulbTemp( float temp, float humidity, float pressure)
{
    float   tempC = wvutilsConvertFToC(temp);
    float   pressureMB = wvutilsConvertINHGToHPA(pressure);
    float   Ewguess, Eguess;
    float   Es = 6.112 * exp(17.67 * tempC / (tempC + 243.5));
    float   Twguess = 0.0;
    float   incr = 10.0;
    int     previoussign = 1;
    int     cursign;
    float   Edifference = 1;
    float   E2 = Es * (humidity/100.0);

    while (fabs(Edifference) > 0.05)
    {
        Ewguess = 6.112 * exp((17.67 * Twguess) / (Twguess + 243.5));
        Eguess = Ewguess - pressureMB * (tempC - Twguess) * 0.00066 * (1.0 + (0.00115 * Twguess));
        Edifference = E2 - Eguess;
        if (Edifference == 0)
        {
            break;
        }
        else
        {
            if (Edifference < 0)
                cursign = -1;
            else cursign = 1;

            if (cursign != previoussign)
            {
                previoussign = cursign;
                incr = incr/10;
            }
        }
        Twguess = Twguess + incr * previoussign;
    }

    return wvutilsConvertCToF(Twguess);
}
Ejemplo n.º 5
0
static void drawGrid (MULTICHART_ID id)
{
    register int    i;
    int             xlabelwidth = 0, ylabelwidth = 0;
    double          units, step;
    double          minR, stepR;
    int             dataPoints, xnumhash, xhashindexlen;
    double          hashwidth, xhashwidth;
    int             numhash, x, y;
    char            text[64][32], ylabelfmt[24];
    char            textR[64][32], ylabelfmtR[24];

    //  ... calculate the maximum number of hash marks and the units per hash
    //  ... for the x-axis
    //  build labels and calculate the maximum x-label width
    for (i = 0; i < id->numpoints; i ++)
    {
        if (strlen (id->pointnames[i]) > xlabelwidth)
            xlabelwidth = strlen (id->pointnames[i]);
    }

    xhashwidth = (xlabelwidth*gdFontSmall->h)/2;
    dataPoints = id->numpoints - 1;


    if (strlen (id->DualUnit) > 0)
    {
        // ((gdFontSmall->h/2) * strlen (id->DualUnit)))/2) - 2
        id->imbx -= (gdFontMediumBold->h);
        if ((strcmp(id->DualUnit,"inches") == 0) || 
            (strcmp(id->DualUnit,"knots") == 0) || 
            (strcmp(id->DualUnit,"m/s") == 0))
            id->imbx -= 7;
    }


    // see if a suggestion was given
    if (id->xnumhashes != 0)
    {
        xnumhash = id->xnumhashes;
    }
    else
    {
        xnumhash =  (id->imbx - id->imtx)/xhashwidth;

        // try to normalize the number of hashmarks
        // try with the endpoint removed
        for (i = 1; i < dataPoints/2; i ++)
        {
            if (dataPoints % i != 0)
                continue;

            if (dataPoints/i <= xnumhash)
            {
                xnumhash = dataPoints/i;
                break;
            }
        }
    }

    xhashwidth = (double)(id->imbx - id->imtx)/(double)xnumhash;
    id->pointpixels = (double)(id->imbx - id->imtx)/(double)dataPoints;
    xhashindexlen = dataPoints/xnumhash;


    //  ... calculate the maximum number of hash marks and the units per hash
    //  ... for the y-axis
    hashwidth = (gdFontSmall->h * 3)/2;
    numhash = (id->imby - id->imty)/hashwidth;
    if (numhash > 64)
        numhash = 64;

    units = (id->max - id->min)/id->ystepSize;
    step = id->ystepSize;
    i = 0;
    while ((int)units > numhash && i < MAX_STEP_MULTIPLIER)
    {
        step = id->ystepSize * stepSizeMultipliers[i];
        units = (id->max - id->min)/step;
        i ++;
    }

    id->ystepSize = step;
    numhash = (int)units;
    if ((id->min + (id->ystepSize * numhash)) < id->max)
    {
        numhash ++;
    }

    hashwidth = (double)(id->imby - id->imty)/(double)numhash;
    id->max = id->min + (id->ystepSize * numhash);
    id->ypixelconstant = (double)(id->imby - id->imty)/(double)(id->max - id->min);
    numhash ++;
    if (numhash > 64)
        numhash = 64;

    //  build labels and calculate the maximum y-label width
    sprintf (ylabelfmt, "%%.%1.1df", id->ydecPlaces);
    for (i = 0; i < numhash; i ++)
    {
        sprintf (text[i], ylabelfmt, id->min + (i * id->ystepSize));

        // now fill the right hand array with alternate scale @Rcm
        if (strlen(id->DualUnit) > 0)
        {
            textR[i][0] = ' ';
            if (strcmp(id->DualUnit,"C") == 0)
            {
                minR = wvutilsConvertFToC (id->min);
                stepR = ((id->ystepSize) * (5.0/9.0));
                sprintf (textR[i], "%.1f", minR + (i * stepR));
            }
            else if (strcmp(id->DualUnit,"F") == 0)
            {
                minR = wvutilsConvertCToF (id->min);
                stepR = ((id->ystepSize) * (9.0/5.0));
                sprintf (textR[i], "%.1f", minR + (i * stepR));
            }
            else if (strcmp(id->DualUnit,"mm") == 0)
            {
                minR = wvutilsConvertINToMM (id->min);
                stepR = wvutilsConvertINToMM (id->ystepSize);
                if (wvutilsConvertINToMM (id->max) >= 100)
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                else
                    sprintf (textR[i], "%.1f", minR + (i * stepR));
            }
            else if (strcmp(id->DualUnit,"inches") == 0)
            {
                minR = wvutilsConvertMMToIN (id->min);
                stepR = wvutilsConvertMMToIN (id->ystepSize);
                if (wvutilsConvertMMToIN (id->max) >= 100)
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                else
                    sprintf (textR[i], "%.1f", minR + (i * stepR));
            }
            else if (strcmp(id->DualUnit,"km/h") == 0)
            {
                minR = wvutilsConvertMilesToKilometers (id->min);
                stepR = wvutilsConvertMilesToKilometers (id->ystepSize);
                sprintf (textR[i], "%.0f", minR + (i * stepR));
            }
            else if (strcmp(id->DualUnit,"mph") == 0)
            {
                minR = wvutilsConvertKilometersToMiles (id->min);
                stepR = wvutilsConvertKilometersToMiles (id->ystepSize);
                sprintf (textR[i], "%.0f", minR + (i * stepR));
            }
            else if (strcmp(id->title,"m/s") == 0)
            {
                if (id->isMetric)
                {
                    minR = wvutilsConvertMPSToKPH (id->min);
                    stepR = wvutilsConvertMPSToKPH (id->ystepSize);
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                }
                else
                {
                    minR = wvutilsConvertMPSToMPH (id->min);
                    stepR = wvutilsConvertMPSToMPH (id->ystepSize);
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                }
            }
            else if (strcmp(id->title,"knots") == 0)
            {
                if (id->isMetric)
                {
                    minR = wvutilsConvertKnotsToKPH (id->min);
                    stepR = wvutilsConvertKnotsToKPH (id->ystepSize);
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                }
                else
                {
                    minR = wvutilsConvertKnotsToMPH (id->min);
                    stepR = wvutilsConvertKnotsToMPH (id->ystepSize);
                    sprintf (textR[i], "%.0f", minR + (i * stepR));
                }
            }
            else //all else: eg '%' or watts/m^2 (hum/ rad)
            {    // same value both sides
                minR = id->min * 25.4;
                stepR = id->ystepSize * 25.4;
                sprintf (textR[i], "%s", text[i]);
            }
            if (strlen (text[i]) > ylabelwidth)
                ylabelwidth = strlen (text[i])+2;
        }
        else
        {

            if (strlen (text[i]) > ylabelwidth)
                ylabelwidth = strlen (text[i]);
        }
    }

    //  ... now we know the chart area, draw it
    gdImageFilledRectangle (id->im,
                            id->imtx - GLC_CONTENTS_OFFSET,
                            id->imty - GLC_CONTENTS_OFFSET,
                            id->imbx + GLC_CONTENTS_OFFSET,
                            id->imby + GLC_CONTENTS_OFFSET,
                            id->chartcolor);

    gdImageRectangle (id->im,
                      id->imtx,
                      id->imty,
                      id->imbx,
                      id->imby,
                      id->gridcolor);

    //  ... draw the y-axis
    gdImageSetThickness (id->im, 1);
    for (i = 0; i < numhash; i ++)
    {
        y = id->imby - (i * hashwidth);

        gdImageLine (id->im,
                     id->imtx,
                     y,
                     id->imbx,
                     y,
                     id->gridcolor);

        y -= gdFontSmall->h/2;
        gdImageString (id->im,
                       gdFontSmall,
                       (id->imtx - 5) - (strlen(text[i]) * gdFontSmall->h/2),
                       y,
                       (UCHAR *)text[i],
                       id->textcolor);

        if (strlen(id->DualUnit) > 0 )
        {
            // right side
            x = id->imbx + (GLC_CONTENTS_OFFSET - 2);

            gdImageString (id->im,
                           gdFontSmall,
                           x + gdFontSmall->h/2,
                           y,
                           (UCHAR *)textR[i],
                           id->textcolor);
        }
    }

    //  ... draw the x-axis
    gdImageSetThickness (id->im, 1);

    for (i = 0; i <= xnumhash; i ++)            // one more for right-most
    {
        int         dataPoint = i * xhashindexlen;

        x = id->imtx + (i * xhashwidth);

        gdImageLine (id->im,
                     x,
                     id->imty,
                     x,
                     id->imby,
                     id->gridcolor);

        if (strlen(id->pointnames[dataPoint]) < 2)
            x -= gdFontSmall->h/4;

        gdImageString (id->im,
                       gdFontSmall,
                       x - ((gdFontSmall->h/2) *
                            (strlen(id->pointnames[dataPoint])/2)),
                       (id->height - (3 * gdFontMediumBold->h)) + 4,
                       (UCHAR *)id->pointnames[dataPoint],
                       id->textcolor);
    }


    //  ... finally, draw date
    gdImageString (id->im,
                   gdFontSmall,
                   ((id->width - ((gdFontSmall->h/2) * strlen (id->datetime)))/2) - 2,
                   id->height - (gdFontMediumBold->h + 2),
                   (UCHAR *)id->datetime,
                   id->textcolor);
}
Ejemplo n.º 6
0
Archivo: alarms.c Proyecto: breu/wview
static void processAlarms (LOOP_PKT *loopData)
{
    WVIEW_ALARM         *alarm;
    float               tempFloat;

    // process the local alarms:
    for (alarm = (WVIEW_ALARM *) radListGetFirst (&alarmsWork.alarmList);
         alarm != NULL;
         alarm = (WVIEW_ALARM *) radListGetNext (&alarmsWork.alarmList, 
                                                 (NODE_PTR)alarm))
    {
        // first check to see if we are in abatement
        if (alarm->triggered)
        {
            if ((radTimeGetSECSinceEpoch () - alarm->abateStart) < alarm->abateSecs)
            {
                // abatement - go to the next alarm
                continue;
            }
            else
            {
                // clear trigger for future alarms
                alarm->triggered = FALSE;
            }
        }

        // switch on alarm type
        switch (alarm->type)
        {
            case Barometer:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertINHGToHPA(loopData->barometer);
                }
                else
                {
                    tempFloat = loopData->barometer;
                }
                break;

            case InsideTemp:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->inTemp);
                }
                else
                {
                    tempFloat = loopData->inTemp;
                }
                break;

            case InsideHumidity:
                tempFloat = (float)loopData->inHumidity;
                break;

            case OutsideTemp:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->outTemp);
                }
                else
                {
                    tempFloat = loopData->outTemp;
                }
                break;

            case WindSpeed:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertMPHToKPH((float)loopData->windSpeed);
                }
                else
                {
                    tempFloat = (float)loopData->windSpeed;
                }
                break;

            case TenMinuteAvgWindSpeed:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertMPHToKPH((float)loopData->tenMinuteAvgWindSpeed);
                }
                else
                {
                    tempFloat = (float)loopData->tenMinuteAvgWindSpeed;
                }
                break;

            case WindDirection:
                tempFloat = (float)loopData->windDir;
                break;

            case OutsideHumidity:
                tempFloat = (float)loopData->outHumidity;
                break;

            case RainRate:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->rainRate);
                }
                else
                {
                    tempFloat = loopData->rainRate;
                }
                break;

            case StormRain:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->stormRain);
                }
                else
                {
                    tempFloat = loopData->stormRain;
                }
                break;

            case DayRain:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->dayRain);
                }
                else
                {
                    tempFloat = loopData->dayRain;
                }
                break;

            case MonthRain:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->monthRain);
                }
                else
                {
                    tempFloat = loopData->monthRain;
                }
                break;

            case YearRain:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->yearRain);
                }
                else
                {
                    tempFloat = loopData->yearRain;
                }
                break;

            case TxBatteryStatus:
                tempFloat = (float)loopData->txBatteryStatus;
                break;

            case ConsoleBatteryVoltage:
                tempFloat = (((float)loopData->consBatteryVoltage * 300)/512)/100;
                break;

            case DewPoint:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->dewpoint);
                }
                else
                {
                    tempFloat = loopData->dewpoint;
                }
                break;

            case WindChill:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->windchill);
                }
                else
                {
                    tempFloat = loopData->windchill;
                }
                break;

            case HeatIndex:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->heatindex);
                }
                else
                {
                    tempFloat = loopData->heatindex;
                }
                break;

            case Radiation:
                tempFloat = (float)loopData->radiation;
                break;

            case UV:
                tempFloat = (float)loopData->UV;
                break;

            case ET:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->dayET);
                }
                else
                {
                    tempFloat = loopData->dayET;
                }
                break;

            case ExtraTemp1:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->extraTemp1);
                }
                else
                {
                    tempFloat = loopData->extraTemp1;
                }
                break;

            case ExtraTemp2:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->extraTemp2);
                }
                else
                {
                    tempFloat = loopData->extraTemp2;
                }
                break;

            case ExtraTemp3:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->extraTemp3);
                }
                else
                {
                    tempFloat = loopData->extraTemp3;
                }
                break;

            case SoilTemp1:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->soilTemp1);
                }
                else
                {
                    tempFloat = loopData->soilTemp1;
                }
                break;

            case SoilTemp2:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->soilTemp2);
                }
                else
                {
                    tempFloat = loopData->soilTemp2;
                }
                break;

            case SoilTemp3:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->soilTemp3);
                }
                else
                {
                    tempFloat = loopData->soilTemp3;
                }
                break;

            case SoilTemp4:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->soilTemp4);
                }
                else
                {
                    tempFloat = loopData->soilTemp4;
                }
                break;

            case LeafTemp1:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->leafTemp1);
                }
                else
                {
                    tempFloat = loopData->leafTemp1;
                }
                break;

            case LeafTemp2:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->leafTemp2);
                }
                else
                {
                    tempFloat = loopData->leafTemp2;
                }
                break;

            case ExtraHumid1:
                tempFloat = (float)loopData->extraHumid1;
                break;

            case ExtraHumid2:
                tempFloat = (float)loopData->extraHumid2;
                break;

            case Wxt510Hail:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->wxt510Hail);
                }
                else
                {
                    tempFloat = loopData->wxt510Hail;
                }
                break;

            case Wxt510Hailrate:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertRainINToMetric(loopData->wxt510Hailrate);
                }
                else
                {
                    tempFloat = loopData->wxt510Hailrate;
                }
                break;

            case Wxt510HeatingTemp:
                if (alarmsWork.isMetric)
                {
                    tempFloat = wvutilsConvertFToC(loopData->wxt510HeatingTemp);
                }
                else
                {
                    tempFloat = loopData->wxt510HeatingTemp;
                }
                break;

            case Wxt510HeatingVoltage:
                tempFloat = loopData->wxt510HeatingVoltage;
                break;

            case Wxt510SupplyVoltage:
                tempFloat = loopData->wxt510SupplyVoltage;
                break;

            case Wxt510ReferenceVoltage:
                tempFloat = loopData->wxt510ReferenceVoltage;
                break;

            default:
                // no match, blow it off
                continue;
        }

        // see if we tripped the breaker here
        if (alarm->isMax)
        {
            if (tempFloat >= alarm->bound)
            {
                // we did!
                alarm->triggered = TRUE;
                alarm->triggerValue = tempFloat;
                alarm->abateStart = radTimeGetSECSinceEpoch ();

                // run user script here
                statusIncrementStat(ALARM_STATS_SCRIPTS_RUN);
                if (executeScript (alarm) != 0)
                {
                    radMsgLog (PRI_MEDIUM, 
                               "processAlarms: script %s failed",
                               alarm->scriptToRun);
                }
            }
        }
        else
        {
            if (tempFloat <= alarm->bound)
            {
                // we did!
                alarm->triggered = TRUE;
                alarm->triggerValue = tempFloat;
                alarm->abateStart = radTimeGetSECSinceEpoch ();

                // run user script here
                statusIncrementStat(ALARM_STATS_SCRIPTS_RUN);
                if (executeScript (alarm) != 0)
                {
                    radMsgLog (PRI_MEDIUM, 
                               "processAlarms: script %s failed",
                               alarm->scriptToRun);
                }
            }
        }
    }

    return;
}