Example #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;
}
Example #2
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);
}
Example #3
0
//  calculate altimeter pressure from station pressure
float wvutilsConvertSPToAltimeter (float SPInches, float elevationFT)
{
    double      magicEXP            = 0.190284;
    double      inverseMagicEXP     = 1 / magicEXP;
    double      elevMeters          = (double)wvutilsConvertFeetToMeters(elevationFT);
    double      stationPressureMB   = (double)wvutilsConvertINHGToHPA(SPInches);
    double      constantTerm;
    double      variableTerm;
    double      tempdouble;
    double      altimeter;

    // Formula used: http://www.wrh.noaa.gov/slc/projects/wxcalc/formulas/altimeterSetting.pdf
    
    // calculate the constant term
    constantTerm =  pow (1013.25, magicEXP);
    constantTerm *= 0.0065;
    constantTerm /= 288;

    // calculate the variable term
    tempdouble = stationPressureMB - 0.3;
    tempdouble = pow (tempdouble, magicEXP);
    variableTerm = elevMeters / tempdouble;

    // compute main term
    tempdouble = constantTerm * variableTerm;
    tempdouble += 1;
    tempdouble = pow (tempdouble, inverseMagicEXP);

    // compute altimeter
    altimeter = stationPressureMB - 0.3;
    altimeter *= tempdouble;

    // finally, convert back to inches
    altimeter *= 0.0295299;
    
    return (float)altimeter;
}
Example #4
0
File: cwop.c Project: breu/wview
static void processCWOP ()
{
    RADSOCK_ID                          socket;
    time_t                              ntime;
    struct tm                           *gmTime;
    char                                cwopBuffer[256], login[64];
    int                                 length = 0;
    char                                *serv;
    int                                 port;
    volatile WVIEW_MSG_ARCHIVE_NOTIFY   Notify;

    memcpy ((void*)&Notify, (void*)&cwopWork.ArchiveMsg, sizeof(WVIEW_MSG_ARCHIVE_NOTIFY));

    // format the CWOP data
    ntime = time (NULL);
    gmTime = gmtime (&ntime);
    length = sprintf (cwopBuffer, "%s>APRS,TCPXX*,qAX,%s:@", 
                      cwopWork.callSign, cwopWork.callSign);
    length += sprintf (&cwopBuffer[length], "%2.2d%2.2d%2.2dz",
                       gmTime->tm_mday, gmTime->tm_hour, gmTime->tm_min);
    length += sprintf (&cwopBuffer[length], "%s/%s",
                       cwopWork.latitude, cwopWork.longitude);

    // check for any wind registered
    if (Notify.wspeed < 0)
    {
        length += sprintf (&cwopBuffer[length], "_...");
    }
    else
    {
        length += sprintf (&cwopBuffer[length], "_%3.3d", Notify.winddir);
    }
    
    length += sprintf (&cwopBuffer[length], "/%3.3d", Notify.wspeed);
    length += sprintf (&cwopBuffer[length], "g%3.3d", Notify.hiwspeed);

    if (Notify.temp < 0)
    {
        if (((Notify.temp * (-1)) % 10) >= 5)
        {
            Notify.temp -= 10;
        }

        length += sprintf (&cwopBuffer[length], "t-%2.2d", 
                           (Notify.temp * (-1))/10);
    }
    else
    {
        if ((Notify.temp % 10) >= 5)
        {
            Notify.temp += 10;
        }

        length += sprintf (&cwopBuffer[length], "t%3.3d", Notify.temp/10);
    }
    
    length += sprintf (&cwopBuffer[length], "P%3.3d", Notify.rainDay);
    
    if (Notify.humidity >= 0 && Notify.humidity <= 100)
    {
        length += sprintf (&cwopBuffer[length], "h%2.2d", Notify.humidity % 100);
    }
    
    length += sprintf (&cwopBuffer[length], "b%5.5d", 
                       (int)(10 * wvutilsConvertINHGToHPA((float)Notify.altimeter/1000.0)));
    sprintf (&cwopBuffer[length], ".%s", wvutilsCreateCWOPVersion(globalWviewVersionStr));


    // connect to the CWOP server - try the primary then secondary then tertiary
    socket = radSocketClientCreate (cwopWork.server1, cwopWork.portNo1);
    if (socket == NULL)
    {
        statusUpdateMessage("CWOP-connect: failed to connect to server");
        statusIncrementStat(CWOP_STATS_CONNECT_ERRORS);
        wvutilsLogEvent (PRI_MEDIUM, "CWOP-connect: failed to connect to %s:%d",
                         cwopWork.server1, cwopWork.portNo1);
        
        // try the secondary server
        socket = radSocketClientCreate (cwopWork.server2, cwopWork.portNo2);
        if (socket == NULL)
        {
            statusUpdateMessage("CWOP-connect: failed to connect to server");
            statusIncrementStat(CWOP_STATS_CONNECT_ERRORS);
            wvutilsLogEvent (PRI_MEDIUM, "CWOP-connect: failed to connect to %s:%d",
                             cwopWork.server2, cwopWork.portNo2);
        
            // try the tertiary server
            socket = radSocketClientCreate (cwopWork.server3, cwopWork.portNo3);
            if (socket == NULL)
            {
                // we are all out of luck this time!
                statusUpdateMessage("CWOP-connect: failed to connect to server");
                statusIncrementStat(CWOP_STATS_CONNECT_ERRORS);
                wvutilsLogEvent (PRI_MEDIUM, "CWOP-connect: failed to connect to %s:%d",
                                 cwopWork.server3, cwopWork.portNo3);
                radMsgLog (PRI_HIGH, 
                           "CWOP-connect: failed to connect to all 3 APRS servers!");
                return;
            }
            else
            {
                serv = cwopWork.server3;
                port = cwopWork.portNo3;
            }
        }
        else
        {
            serv = cwopWork.server2;
            port = cwopWork.portNo2;
        }
    }
    else
    {
        serv = cwopWork.server1;
        port = cwopWork.portNo1;
    }
    
    // wait 1 second ...
    radUtilsSleep (1000);
    
    // transmit the data 
    sprintf (login, "user %6s pass %d vers %s", 
             cwopWork.callSign, 
             (int)getPasscode(cwopWork.callSign), 
             globalWviewVersionStr);
    length = strlen (login);
    login[length] = 0x0D;           // tack on the CR and LF
    login[length+1] = 0x0A;
    login[length+2] = 0;
    
    if (radSocketWriteExact (socket, login, length + 2) != (length + 2))
    {
        statusUpdateMessage("CWOP-error: failed to login to server");
        radMsgLog (PRI_HIGH, "CWOP-error: %d: failed to login to %s:%d!",
                   errno, serv, port);
        radSocketDestroy (socket);
        return;
    }
    
    // wait 3 seconds ...
    radUtilsSleep (3000);
    
    // write the data record
    wvutilsLogEvent (PRI_STATUS, "CWOP-send: %s", cwopBuffer);

    length = strlen (cwopBuffer);
    cwopBuffer[length] = 0x0D;       // tack on the CR and LF
    cwopBuffer[length+1] = 0x0A;
    cwopBuffer[length+2] = 0;
    if (radSocketWriteExact (socket, cwopBuffer, length + 2) != (length + 2))
    {
        statusUpdateMessage("CWOP-error: failed to write to server");
        radMsgLog (PRI_HIGH, "CWOP-error: %d: failed to write to %s:%d!",
                   errno, serv, port);
        radSocketDestroy (socket);
        return;
    }

    statusIncrementStat(CWOP_STATS_PKTS_SENT);

    // wait 3 more seconds ...
    radUtilsSleep (3000);

    // close connection and cleanup
    radSocketDestroy (socket);

    return;
}
Example #5
0
File: alarms.c Project: 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;
}