Ejemplo n.º 1
0
void multiChartAddPoint (MULTICHART_ID id, double *values, char *name)
{
    int             i;

    if (id->numpoints >= MAX_GRAPH_POINTS)
    {
        return;
    }

    for (i = 0; i < id->numdatasets; i ++)
    {
        id->dataset[i].valueset[id->numpoints] = values[i];

        if (values[i] > ARCHIVE_VALUE_NULL)
        {
            if (values[i] < id->min)
                normalizeMinMax (id, values[i], id->max);
            else if (values[i] > id->max)
                normalizeMinMax (id, id->min, values[i]);
        }
    }

    wvstrncpy (id->pointnames[id->numpoints], name, sizeof(id->pointnames[id->numpoints]));
    id->numpoints ++;

    return;
}
Ejemplo n.º 2
0
MULTICHART_ID multiChartCreate
(
    int                     width,
    int                     height,
    char                    *title,
    int                     numDataSets,
    char                    *legends[]
)
{
    int                     i;
    register MULTICHART_ID  newId;

    newId = &nonReentrantMultiChart;

    memset (newId, 0, sizeof (*newId));

    if (numDataSets > MC_MAX_DATA_SETS)
        numDataSets = MC_MAX_DATA_SETS;
    newId->numdatasets = numDataSets;

    for (i = 0; i < numDataSets; i ++)
    {
        wvstrncpy (newId->dataset[i].legend, legends[i], sizeof(newId->dataset[i].legend));
    }

    newId->width = width;
    newId->height = height;
    wvstrncpy (newId->title, title, sizeof(newId->title));

    //  ... now set the contents coords
    newId->imtx = 5 * gdFontSmall->h/2;
    //  ... SSM: move the right edge of the graph 5 pixels left to make
    //  ...      room for last label
    newId->imbx = (newId->width - 1) - gdFontMediumBold->h - 5;
    newId->imty = 2 * gdFontMediumBold->h;
    newId->imby = newId->height - (3 * gdFontMediumBold->h);

    newId->bgcolor      = GLC_DFLT_BG;
    newId->chartcolor   = GLC_DFLT_CHART;
    newId->gridcolor    = GLC_DFLT_GRID;
    newId->titleFGcolor = GLC_DFLT_TITLEFG;
    newId->titleBGcolor = GLC_DFLT_TITLEBG;
    newId->textcolor    = GLC_DFLT_TEXT;

    return newId;
}
Ejemplo n.º 3
0
static int readHtmlTemplateFile (HTML_MGR *mgr, char *filename)
{
    HTML_TMPL       *html;
    FILE            *file;
    char            *token;
    char            temp[HTML_MAX_LINE_LENGTH];

    file = fopen (filename, "r");
    if (file == NULL)
    {
        radMsgLog (PRI_HIGH, "htmlmgrInit: %s does not exist!",
                   filename);
        return ERROR_ABORT;
    }

    while (fgets (temp, HTML_MAX_LINE_LENGTH, file) != NULL)
    {
        if (temp[0] == ' ' || temp[0] == '\n' || temp[0] == '#')
        {
            // comment or whitespace
            continue;
        }

        html = (HTML_TMPL *)malloc (sizeof (*html));
        if (html == NULL)
        {
            for (html = (HTML_TMPL *)radListRemoveFirst (&mgr->templateList);
                 html != NULL;
                 html = (HTML_TMPL *)radListRemoveFirst (&mgr->templateList))
            {
                free (html);
            }

            fclose (file);
            return ERROR;
        }

        // do the template file name
        token = strtok (temp, " \t\n");
        if (token == NULL)
        {
            free (html);
            continue;
        }
        wvstrncpy (html->fname, token, sizeof(html->fname));

        radListAddToEnd (&mgr->templateList, (NODE_PTR)html);
    }

    fclose (file);
    return OK;
}
Ejemplo n.º 4
0
Archivo: alarms.c Proyecto: breu/wview
static int executeScript (WVIEW_ALARM *alarm)
{
    int             retVal;
    char            *args[5];
    char            path[_MAX_PATH];
    char            type[64];
    char            thresh[64];
    char            trigVal[64];

    wvstrncpy (path, alarm->scriptToRun, _MAX_PATH);
    args[0] = path;

    sprintf (type, "%d", alarm->type);
    args[1] = type;

    sprintf (thresh, "%.3f", alarm->bound);
    args[2] = thresh;

    sprintf (trigVal, "%.3f", alarm->triggerValue);
    args[3] = trigVal;

    args[4] = 0;

    retVal = fork ();
    if (retVal == -1)
    {
        return -1;
    }
    else if (retVal == 0)
    {
        // we are the child!
        if (execv (path, args) == -1)
        {
            radMsgLog(PRI_HIGH, "executeScript: execv(%s) failed: %s", path, strerror(errno));
            exit(-1);
        }
        exit(0);
    }
    else
    {
        // we are the parent, pause a bit to let the script run 
        // and avoid a process "storm"
        radUtilsSleep (50);                 // 50 ms
    }

    return 0;
}
Ejemplo n.º 5
0
Archivo: cwop.c Proyecto: breu/wview
/*  ... the main entry point for the wvcwopd process
*/
int main (int argc, char *argv[])
{
    void            (*alarmHandler)(int);
    int             retVal;
    FILE            *pidfile;
    int             iValue;
    double          dValue;
    const char*     sValue;
    int             runAsDaemon = TRUE;

    if (argc > 1)
    {
        if (!strcmp(argv[1], "-f"))
        {
            runAsDaemon = FALSE;
        }
    }

    memset (&cwopWork, 0, sizeof (cwopWork));

    /*  ... initialize some system stuff first
    */
    retVal = cwopSysInit (&cwopWork);
    if (retVal == ERROR)
    {
        radMsgLogInit (PROC_NAME_CWOP, FALSE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "wvcwopd init failed!");
        radMsgLogExit ();
        exit (1);
    }
    else if (retVal == ERROR_ABORT)
    {
        exit (2);
    }


    /*  ... call the global radlib system init function
    */
    if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR)
    {
        radMsgLogInit (PROC_NAME_CWOP, TRUE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!");
        radMsgLogExit ();
        exit (1);
    }


    /*  ... call the radlib process init function
    */
    if (radProcessInit (PROC_NAME_CWOP,
                        cwopWork.fifoFile,
                        PROC_NUM_TIMERS_CWOP,
                        runAsDaemon,                // TRUE for daemon
                        msgHandler,
                        evtHandler,
                        NULL)
        == ERROR)
    {
        printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_CWOP);
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    cwopWork.myPid = getpid ();
    pidfile = fopen (cwopWork.pidFile, "w");
    if (pidfile == NULL)
    {
        radMsgLog (PRI_CATASTROPHIC, "lock file create failed!");
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    fprintf (pidfile, "%d", getpid ());
    fclose (pidfile);


    alarmHandler = radProcessSignalGetHandler (SIGALRM);
    radProcessSignalCatchAll (defaultSigHandler);
    radProcessSignalCatch (SIGALRM, alarmHandler);
    radProcessSignalRelease(SIGABRT);


    //  get our configuration values
    if (wvconfigInit(FALSE) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!");
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // Is the CWOP daemon enabled?
    iValue = wvconfigGetBooleanValue(configItem_ENABLE_CWOP);
    if (iValue == ERROR || iValue == 0)
    {
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "CWOP daemon is NOT enabled - exiting...");
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // get the wview verbosity setting
    if (wvutilsSetVerbosity (WV_VERBOSE_WVCWOPD) == ERROR)
    {
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!");
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // get the APRS call sign
    sValue = wvconfigGetStringValue(configItemCWOP_APRS_CALL_SIGN);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_CALL_SIGN);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.callSign, sValue, sizeof(cwopWork.callSign));
        if (sValue[strlen(sValue)-1] >= '0' && sValue[strlen(sValue)-1] <= '9')
        {
            cwopWork.callSignOffset = atoi(&sValue[strlen(sValue)-1]);
        }
        else
        {
            cwopWork.callSignOffset = (sValue[strlen(sValue)-1] % 10);
        }
        cwopWork.callSignOffset %= 10;
    }

    // get the primary APRS server
    sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER1);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER1);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.server1, sValue, sizeof(cwopWork.server1));
    }

    // get the primary APRS port number
    iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO1);
    if (iValue < 0)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO1);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        cwopWork.portNo1 = iValue;
    }

    // get the secondary APRS server
    sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER2);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER2);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.server2, sValue, sizeof(cwopWork.server2));
    }

    // get the primary APRS port number
    iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO2);
    if (iValue < 0)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO2);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        cwopWork.portNo2 = iValue;
    }

    // get the tertiary APRS server
    sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER3);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER3);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.server3, sValue, sizeof(cwopWork.server3));
    }

    // get the primary APRS port number
    iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO3);
    if (iValue < 0)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO3);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        cwopWork.portNo3 = iValue;
    }

    // get the fine pitch latitude that APRS requires
    sValue = wvconfigGetStringValue(configItemCWOP_LATITUDE);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_LATITUDE);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.latitude, sValue, sizeof(cwopWork.latitude));
    }

    // get the fine pitch longitude that APRS requires
    sValue = wvconfigGetStringValue(configItemCWOP_LONGITUDE);
    if (sValue == NULL)
    {
        // we can't do without this!
        wvconfigExit ();
        radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_LONGITUDE);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        wvstrncpy (cwopWork.longitude, sValue, sizeof(cwopWork.longitude));
    }

    // get the WX packet logging preference
    iValue = wvconfigGetBooleanValue(configItemCWOP_LOG_WX_PACKET);
    if (iValue <= 0)
    {
        // just disable it
        cwopWork.logWXPackets = 0;
    }
    else
    {
        cwopWork.logWXPackets = iValue;
    }

    wvconfigExit ();


    if (statusInit(cwopWork.statusFile, cwopStatusLabels) == ERROR)
    {
        radMsgLog (PRI_HIGH, "statusInit failed - exiting...");
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    statusUpdate(STATUS_BOOTING);


    // wait a bit here before continuing
    radUtilsSleep (500);


    cwopWork.timer = radTimerCreate (NULL, timerHandler, NULL);
    if (cwopWork.timer == NULL)
    {
        statusUpdateMessage("radTimerCreate failed");
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    radProcessTimerStart (cwopWork.timer, CWOP_MINUTE_INTERVAL);


    //  register with the radlib message router
    if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR)
    {
        statusUpdateMessage("radMsgRouterInit failed");
        radMsgLog (PRI_HIGH, "radMsgRouterInit failed!");
        statusUpdate(STATUS_ERROR);
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // enable message reception from the radlib router for SHUTDOWN msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_SHUTDOWN);


    // wait for the wview daemon to be ready
    if (waitForWviewDaemon () == ERROR)
    {
        radMsgLog (PRI_HIGH, "waitForWviewDaemon failed");
        statusUpdate(STATUS_ERROR);
        radMsgRouterExit ();
        cwopSysExit (&cwopWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // enable message reception from the radlib router for archive notifications
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ARCHIVE_NOTIFY);

    // enable message reception from the radlib router for POLL msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL);


    radMsgLog (PRI_STATUS, "CWOP: configured to submit station %s data to:",
               cwopWork.callSign);
    radMsgLog (PRI_STATUS, "CWOP: Primary:   %s:%d", cwopWork.server1, cwopWork.portNo1);
    radMsgLog (PRI_STATUS, "CWOP: Secondary: %s:%d", cwopWork.server2, cwopWork.portNo2);
    radMsgLog (PRI_STATUS, "CWOP: Tertiary:  %s:%d", cwopWork.server3, cwopWork.portNo3);
    radMsgLog (PRI_STATUS, "CWOP: Submitting every %d minutes at offset minute: %d",
               cwopWork.reportInterval, cwopWork.callSignOffset);


    // enter normal processing
    cwopWork.inMainLoop = TRUE;
    statusUpdate(STATUS_RUNNING);
    statusUpdateMessage("Normal operation");
    radMsgLog (PRI_STATUS, "running...");


    while (!cwopWork.exiting)
    {
        // wait on something interesting
        if (radProcessWait (0) == ERROR)
        {
            cwopWork.exiting = TRUE;
        }
    }


    statusUpdateMessage("exiting normally");
    radMsgLog (PRI_STATUS, "exiting normally...");
    statusUpdate(STATUS_SHUTDOWN);

    radMsgRouterExit ();
    radTimerDelete (cwopWork.timer);
    cwopSysExit (&cwopWork);
    radProcessExit ();
    radSystemExit (WVIEW_SYSTEM_ID);
    exit (0);
}
Ejemplo n.º 6
0
Archivo: daemon.c Proyecto: breu/wview
/*  ... the main entry point for the daemon process
*/
int main (int argc, char *argv[])
{
    void            (*alarmHandler)(int);
    FILE            *pidfile;
    int             iValue;
    double          dValue;
    const char*     sValue;
    int             runAsDaemon = TRUE;

    if (argc > 1)
    {
        if (!strcmp(argv[1], "-f"))
        {
            runAsDaemon = FALSE;
        }
    }

    /*  ... start with a clean slate
    */
    memset (&wviewdWork, 0, sizeof (wviewdWork));

    /*  ... initialize some system stuff first
    */
    if (daemonSysInit (&wviewdWork) == -1)
    {
        radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "system init failed!\n");
        radMsgLogExit ();
        exit (1);
    }


    /*  ... call the global radlib system init function
    */
    if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR)
    {
        radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!");
        radMsgLogExit ();
        exit (1);
    }


    /*  ... call the radlib process init function
    */
    if (radProcessInit (PROC_NAME_DAEMON,
                        wviewdWork.fifoFile,
                        PROC_NUM_TIMERS_DAEMON,
                        runAsDaemon,                // TRUE for daemon
                        msgHandler,
                        evtHandler,
                        NULL)
        == ERROR)
    {
        printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_DAEMON);
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    wviewdWork.myPid = getpid ();
    pidfile = fopen (wviewdWork.pidFile, "w");
    if (pidfile == NULL)
    {
        radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n");
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    fprintf (pidfile, "%d", getpid ());
    fclose (pidfile);


    alarmHandler = radProcessSignalGetHandler (SIGALRM);
    radProcessSignalCatchAll (defaultSigHandler);
    radProcessSignalCatch (SIGALRM, alarmHandler);
    radProcessSignalRelease(SIGABRT);


    radMsgLog (PRI_STATUS, "%s starting ...", globalWviewVersionStr);
    radTimeGetMSSinceEpoch();
    wvutilsDetectDSTInit();

    // get our configuration values:
    if (wvconfigInit(TRUE) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "config database is missing!!!\n");
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // get the wview verbosity setting
    if (wvutilsSetVerbosity (WV_VERBOSE_WVIEWD) == ERROR)
    {
        wvconfigExit();
        radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!");
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    ///// STATION_INTERFACE PROCESSING BEGIN /////
    sValue = wvconfigGetStringValue(configItem_STATION_STATION_TYPE);
    if (sValue == NULL)
    {
        radMsgLog (PRI_MEDIUM,
                   "no station type given, defaulting to 'VantagePro'...");
        strcpy (wviewdWork.stationType, "VantagePro");
    }
    else
    {
        wvstrncpy(wviewdWork.stationType, sValue, sizeof(wviewdWork.stationType));
    }

    if ((!strcmp(wviewdWork.stationType, "WMRUSB")) ||
        (!strcmp(wviewdWork.stationType, "WH1080")))
    {
        // USB stations:
        radMsgLog (PRI_MEDIUM,
                   "station interface: native USB ...");
    }
    else
    {
        sValue = wvconfigGetStringValue(configItem_STATION_STATION_INTERFACE);
        if (sValue == NULL)
        {
            radMsgLog (PRI_MEDIUM,
                       "no station interface given, defaulting to 'serial'...");
            strcpy (wviewdWork.stationInterface, "serial");
        }
        else
        {
            wvstrncpy(wviewdWork.stationInterface, sValue, sizeof(wviewdWork.stationInterface));
        }
    
        // process the interface type
        if (!strcmp (wviewdWork.stationInterface, "serial"))
        {
            radMsgLog (PRI_MEDIUM,
                       "station interface: serial ...");
    
            // we need a device name for serial IFs
            sValue = wvconfigGetStringValue(configItem_STATION_STATION_DEV);
            if (sValue == NULL)
            {
                wvconfigExit();
                radMsgLog (PRI_CATASTROPHIC,
                           "no serial device given, aborting...");
                daemonSysExit (&wviewdWork);
                radProcessExit ();
                radSystemExit (WVIEW_SYSTEM_ID);
                exit (1);
            }
            else
            {
                wvstrncpy(wviewdWork.stationDevice, sValue, sizeof(wviewdWork.stationDevice));
            }
    
            // grab the DTR toggle flag:
            iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_DTR);
            if (iValue >= 0)
            {
                wviewdWork.stationToggleDTR = iValue;
            }
            else
            {
                wviewdWork.stationToggleDTR = TRUE;
            }
        }
        else if (!strcmp (wviewdWork.stationInterface, "ethernet"))
        {
            radMsgLog (PRI_MEDIUM,
                       "station interface: ethernet ...");
    
            // we need host and port for ethernet
            sValue = wvconfigGetStringValue(configItem_STATION_STATION_HOST);
            if (sValue == NULL)
            {
                wvconfigExit();
                radMsgLog (PRI_CATASTROPHIC,
                           "no hostname given, aborting...");
                daemonSysExit (&wviewdWork);
                radProcessExit ();
                radSystemExit (WVIEW_SYSTEM_ID);
                exit (1);
            }
            else
            {
                wvstrncpy(wviewdWork.stationHost, sValue, sizeof(wviewdWork.stationHost));
    
                iValue = wvconfigGetINTValue(configItem_STATION_STATION_PORT);
                if (iValue <= 0)
                {
                    wvconfigExit();
                    radMsgLog (PRI_CATASTROPHIC,
                               "no port given, aborting...");
                    daemonSysExit (&wviewdWork);
                    radProcessExit ();
                    radSystemExit (WVIEW_SYSTEM_ID);
                    exit (1);
                }
                else
                {
                    wviewdWork.stationPort = iValue;
    
                    // grab the Weatherlink IP flag:
                    iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_WLIP);
                    if (iValue >= 0)
                    {
                        wviewdWork.stationIsWLIP = iValue;
                    }
                    else
                    {
                        wviewdWork.stationIsWLIP = FALSE;
                    }
    
                }
            }
        }
        else
        {
            // invalid type specified - abort
            wvconfigExit();
            radMsgLog (PRI_CATASTROPHIC,
                       "invalid STATION_INTERFACE %s given, aborting...",
                       wviewdWork.stationInterface);
            daemonSysExit (&wviewdWork);
            radProcessExit ();
            radSystemExit (WVIEW_SYSTEM_ID);
            exit (1);
        }
    }
    ///// STATION_INTERFACE PROCESSING END /////

    iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_SEASON_START);
    if (iValue <= 0)
    {
        radMsgLog (PRI_MEDIUM, "Rain Season Start Month not found - defaulting to 1 (JAN)...\n");
        wviewdWork.stationRainSeasonStart = 1;
    }
    else
    {
        wviewdWork.stationRainSeasonStart = iValue;
        if (wviewdWork.stationRainSeasonStart < 1 ||
            wviewdWork.stationRainSeasonStart > 12)
        {
            radMsgLog (PRI_MEDIUM, "Invalid Rain Season Start Month %d found - defaulting to 1 (JAN)...\n",
                       wviewdWork.stationRainSeasonStart);
            wviewdWork.stationRainSeasonStart = 1;
        }
        else
        {
            radMsgLog (PRI_STATUS, "Rain Season Start Month set to %d\n",
                       wviewdWork.stationRainSeasonStart);
        }
    }

    dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_STORM_TRIGGER_START);
    if (dValue <= 0.0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no rain storm start trigger given, defaulting to 0.05 in/hr...");
        wviewdWork.stationRainStormTrigger = 0.05;
    }
    else
    {
        wviewdWork.stationRainStormTrigger = (float)dValue;
        radMsgLog (PRI_STATUS, "Rain Storm Start Trigger set to %5.2f in/hr\n",
                   wviewdWork.stationRainStormTrigger);
    }

    iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_STORM_IDLE_STOP);
    if (iValue <= 0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no rain storm idle stop time given, defaulting to 12 hours...");
        wviewdWork.stationRainStormIdleHours = 12;
    }
    else
    {
        wviewdWork.stationRainStormIdleHours = iValue;
        radMsgLog (PRI_STATUS, "Rain Storm Stop Time set to %d hours\n",
                   wviewdWork.stationRainStormIdleHours);
    }

    dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_YTD);
    if (dValue < 0.0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no rain YTD preset given, defaulting to 0.00 inches...");
        wviewdWork.stationRainStormIdleHours = 12;
    }
    else
    {
        wviewdWork.stationRainYTDPreset = (float)dValue;
        radMsgLog (PRI_STATUS, "Rain YTD preset set to %.2f inches\n",
                   wviewdWork.stationRainYTDPreset);
    }

    dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_ET_YTD);
    if (dValue < 0.0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no ET YTD preset given, defaulting to 0.000 inches...");
        wviewdWork.stationETYTDPreset = 0;
    }
    else
    {
        wviewdWork.stationETYTDPreset = (float)dValue;
        radMsgLog (PRI_STATUS, "ET YTD preset set to %.3f inches\n",
                   wviewdWork.stationETYTDPreset);
    }

    iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_ET_YTD_YEAR);
    if (iValue < 0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no rain/ET YTD Year given, disabling...");
        wviewdWork.stationRainETPresetYear = 0;
    }
    else
    {
        wviewdWork.stationRainETPresetYear = iValue;
        if (wviewdWork.stationRainETPresetYear < 2000 ||
            wviewdWork.stationRainETPresetYear > 3000)
        {
            radMsgLog (PRI_MEDIUM,
                   "bad rain/ET YTD Year given, disabling...");
            wviewdWork.stationRainETPresetYear = 0;
        }
        else
        {
            radMsgLog (PRI_STATUS, "rain/ET YTD preset Year set to %d\n",
                       wviewdWork.stationRainETPresetYear);
        }
    }

    iValue = wvconfigGetINTValue(configItem_STATION_POLL_INTERVAL);
    if (iValue < 0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no POLL_INTERVAL retrieved, setting to 30 seconds...");
        wviewdWork.cdataInterval = 30000;
    }
    else
    {
        wviewdWork.cdataInterval = iValue * 1000;
    }

    if (((wviewdWork.cdataInterval % 1000) != 0) ||
        ((wviewdWork.cdataInterval/1000) > 60) ||
        ((60 % (wviewdWork.cdataInterval/1000)) != 0))
    {
        radMsgLog (PRI_MEDIUM,
                   "station polling interval %d found in wview.conf is invalid:",
                   wviewdWork.cdataInterval);
        radMsgLog (PRI_MEDIUM,
                   "defaulting to 30 seconds ...");
        radMsgLog (PRI_MEDIUM,
                   "Note: station polling interval must be less than 60 seconds");
        radMsgLog (PRI_MEDIUM,
                   "      and an even divisor of 60 seconds (10000, 15000, 30000)");
        wviewdWork.cdataInterval = 30 * 1000;
    }
    else
    {
        radMsgLog (PRI_STATUS, "station polling interval set to %d seconds",
                   (wviewdWork.cdataInterval/1000));
    }

    iValue = wvconfigGetINTValue(configItem_STATION_PUSH_INTERVAL);
    if (iValue < 0)
    {
        radMsgLog (PRI_MEDIUM,
                   "no PUSH_INTERVAL retrieved, setting to 60 seconds...");
        wviewdWork.pushInterval = 60000;
    }
    else
    {
        wviewdWork.pushInterval = iValue * 1000;
    }


    // Calibration configuration:
    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_BAROMETER);
    if (dValue <= 0.0)
    {
        wviewdWork.calMBarometer = 1.00;
    }
    else
    {
        wviewdWork.calMBarometer = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_BAROMETER);
    wviewdWork.calCBarometer = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_PRESSURE);
    if (dValue <= 0.0)
    {
        wviewdWork.calMPressure = 1.00;
    }
    else
    {
        wviewdWork.calMPressure = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_PRESSURE);
    wviewdWork.calCPressure = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_ALTIMETER);
    if (dValue <= 0.0)
    {
        wviewdWork.calMAltimeter = 1.00;
    }
    else
    {
        wviewdWork.calMAltimeter = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_ALTIMETER);
    wviewdWork.calCAltimeter = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INTEMP);
    if (dValue <= 0.0)
    {
        wviewdWork.calMInTemp = 1.00;
    }
    else
    {
        wviewdWork.calMInTemp = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INTEMP);
    wviewdWork.calCInTemp = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTTEMP);
    if (dValue <= 0.0)
    {
        wviewdWork.calMOutTemp = 1.00;
    }
    else
    {
        wviewdWork.calMOutTemp = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTTEMP);
    wviewdWork.calCOutTemp = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INHUMIDITY);
    if (dValue <= 0.0)
    {
        wviewdWork.calMInHumidity = 1.00;
    }
    else
    {
        wviewdWork.calMInHumidity = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INHUMIDITY);
    wviewdWork.calCInHumidity = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTHUMIDITY);
    if (dValue <= 0.0)
    {
        wviewdWork.calMOutHumidity = 1.00;
    }
    else
    {
        wviewdWork.calMOutHumidity = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTHUMIDITY);
    wviewdWork.calCOutHumidity = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDSPEED);
    if (dValue <= 0.0)
    {
        wviewdWork.calMWindSpeed = 1.00;
    }
    else
    {
        wviewdWork.calMWindSpeed = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDSPEED);
    wviewdWork.calCWindSpeed = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDDIR);
    if (dValue <= 0.0)
    {
        wviewdWork.calMWindDir = 1.00;
    }
    else
    {
        wviewdWork.calMWindDir = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDDIR);
    wviewdWork.calCWindDir = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAIN);
    if (dValue <= 0.0)
    {
        wviewdWork.calMRain = 1.00;
    }
    else
    {
        wviewdWork.calMRain = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAIN);
    wviewdWork.calCRain = dValue;

    dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAINRATE);
    if (dValue <= 0.0)
    {
        wviewdWork.calMRainRate = 1.00;
    }
    else
    {
        wviewdWork.calMRainRate = dValue;
    }
    dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAINRATE);
    wviewdWork.calCRainRate = dValue;

    iValue = wvconfigGetBooleanValue(configItem_ENABLE_EMAIL);
    if (iValue >= 0)
    {
        wviewdWork.IsAlertEmailsEnabled = iValue;
    }
    if (wviewdWork.IsAlertEmailsEnabled)
    {
        sValue = wvconfigGetStringValue(configItem_TO_EMAIL_ADDRESS);
        if (sValue == NULL)
        {
            radMsgLog (PRI_HIGH, "NO alert email TO address given - disabling email alerts...");
            wviewdWork.IsAlertEmailsEnabled = 0;
        }
        else
        {
            wvstrncpy (wviewdWork.alertEmailToAdrs, sValue, sizeof(wviewdWork.alertEmailToAdrs));
        }
        sValue = wvconfigGetStringValue(configItem_FROM_EMAIL_ADDRESS);
        if (sValue == NULL)
        {
            radMsgLog (PRI_HIGH, "NO alert email FROM address given - disabling email alerts...");
            wviewdWork.IsAlertEmailsEnabled = 0;
        }
        else
        {
            wvstrncpy (wviewdWork.alertEmailFromAdrs, sValue, sizeof(wviewdWork.alertEmailFromAdrs));
        }
        iValue = wvconfigGetBooleanValue(configItem_SEND_TEST_EMAIL);
        if (iValue >= 0)
        {
            wviewdWork.IsTestEmailEnabled = iValue;
        }
    }
    iValue = wvconfigGetBooleanValue(configItem_HTMLGEN_STATION_SHOW_IF);
    if (iValue >= 0)
    {
        wviewdWork.showStationIF = iValue;
    }
    else
    {
        wviewdWork.showStationIF = TRUE;
    }

    wvconfigExit ();

    if (statusInit(wviewdWork.statusFile, wviewStatusLabels) == ERROR)
    {
        radMsgLog (PRI_HIGH, "statusInit failed - exiting...");
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    statusUpdate(STATUS_BOOTING);

    // ... Initialize the archive database interface:
    if (dbsqliteArchiveInit() == ERROR)
    {
        radMsgLog (PRI_HIGH, "dbsqliteArchiveInit failed");
        statusUpdateMessage("dbsqliteArchiveInit failed");
        statusUpdate(STATUS_ERROR);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }


    // Initialize timers:
    wviewdWork.archiveTimer = radTimerCreate (NULL, archiveTimerHandler, NULL);
    if (wviewdWork.archiveTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        statusUpdateMessage("radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    wviewdWork.cdataTimer = radTimerCreate (NULL, cdtimerHandler, NULL);
    if (wviewdWork.cdataTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        statusUpdateMessage("radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    wviewdWork.pushTimer = radTimerCreate (NULL, pushTimerHandler, NULL);
    if (wviewdWork.pushTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        statusUpdateMessage("radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    wviewdWork.syncTimer = radTimerCreate (NULL, syncTimerHandler, NULL);
    if (wviewdWork.syncTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "sync radTimerCreate failed");
        statusUpdateMessage("radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.pushTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    wviewdWork.ifTimer = radTimerCreate (NULL, ifTimerHandler, NULL);
    if (wviewdWork.ifTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "sync radTimerCreate failed");
        statusUpdateMessage("radTimerCreate failed");
        statusUpdate(STATUS_ERROR);
        radTimerDelete (wviewdWork.syncTimer);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.pushTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    radProcessEventsAdd (STATION_INIT_COMPLETE_EVENT);
    radProcessEventsAdd (STATION_LOOP_COMPLETE_EVENT);

    //  register with the radlib message router
    if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR)
    {
        radMsgLog (PRI_HIGH, "radMsgRouterInit failed!");
        statusUpdateMessage("radMsgRouterInit failed");
        statusUpdate(STATUS_ERROR);
        radTimerDelete (wviewdWork.ifTimer);
        radTimerDelete (wviewdWork.syncTimer);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.pushTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // enable message reception from the radlib router for worker requests
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_REQUEST);

    // enable message reception from the radlib router for POLL msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL);

    // enable message reception from the radlib router for ALERT msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ALERT);

    // enable message reception from the radlib router for STATION_DATA msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_STATION_DATA);


    // Initialize the HILOW database interface:
    // (this cannot occur before the MsgRouter is initialized)
    if (dbsqliteHiLowInit(TRUE) == ERROR)
    {
        radMsgLog (PRI_HIGH, "dbsqliteHiLowInit failed");
        statusUpdateMessage("dbsqliteHiLowInit failed");
        statusUpdate(STATUS_ERROR);
        stationSendShutdown(&wviewdWork);
        radMsgRouterExit ();
        radTimerDelete (wviewdWork.ifTimer);
        radTimerDelete (wviewdWork.syncTimer);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.pushTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }


    // initialize the station abstraction
    radMsgLog (PRI_STATUS, "-- Station Init Start --");
    if (stationInit (&wviewdWork, daemonArchiveIndication) == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit failed!");
        statusUpdateMessage("stationInit failed");
        statusUpdate(STATUS_ERROR);
        stationSendShutdown(&wviewdWork);
        radMsgRouterExit ();
        radTimerDelete (wviewdWork.ifTimer);
        radTimerDelete (wviewdWork.syncTimer);
        radTimerDelete (wviewdWork.cdataTimer);
        radTimerDelete (wviewdWork.pushTimer);
        radTimerDelete (wviewdWork.archiveTimer);
        daemonSysExit (&wviewdWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // register the station interface if it is device-based:
    if (wviewdWork.medium.type == MEDIUM_TYPE_DEVICE)
    {
        if (radProcessIORegisterDescriptor (wviewdWork.medium.fd,
                                            stationDataCallback,
                                            NULL)
            == ERROR)
        {
            radMsgLog (PRI_HIGH, "IORegDescriptor failed");
            statusUpdateMessage("IORegDescriptor failed");
            statusUpdate(STATUS_ERROR);
            stationSendShutdown(&wviewdWork);
            radMsgRouterExit ();
            radTimerDelete (wviewdWork.ifTimer);
            radTimerDelete (wviewdWork.syncTimer);
            radTimerDelete (wviewdWork.cdataTimer);
            radTimerDelete (wviewdWork.pushTimer);
            radTimerDelete (wviewdWork.archiveTimer);
            stationExit (&wviewdWork);
            daemonSysExit (&wviewdWork);
            radProcessExit ();
            radSystemExit (WVIEW_SYSTEM_ID);
            exit (1);
        }
    }

    // Send test email if it is enabled:
    if (wviewdWork.IsTestEmailEnabled)
    {
        radMsgLog(PRI_STATUS, "Sending test email...");
        emailAlertSend(ALERT_TYPE_TEST);
    }


    statusUpdate(STATUS_RUNNING);
    statusUpdateMessage("Normal operation");
    radMsgLog (PRI_STATUS, "running...");


    while (!wviewdWork.exiting)
    {
        // wait on timers, events, file descriptors, msgs
        if (radProcessWait (0) == ERROR)
        {
            wviewdWork.exiting = TRUE;
        }
    }


    statusUpdateMessage("exiting normally");
    radMsgLog (PRI_STATUS, "exiting normally...");
    statusUpdate(STATUS_SHUTDOWN);

    computedDataExit (&wviewdWork);
    radMsgRouterExit ();
    radTimerDelete (wviewdWork.ifTimer);
    radTimerDelete (wviewdWork.syncTimer);
    radTimerDelete (wviewdWork.pushTimer);
    radTimerDelete (wviewdWork.cdataTimer);
    radTimerDelete (wviewdWork.archiveTimer);
    stationExit (&wviewdWork);
    dbsqliteHiLowExit();
    dbsqliteArchiveExit();
    daemonSysExit (&wviewdWork);
    radProcessExit ();
    radSystemExit (WVIEW_SYSTEM_ID);
    exit (0);
}
Ejemplo n.º 7
0
// station-supplied init function
// -- Can Be Asynchronous - event indication required --
//
// MUST:
//   - set the 'stationGeneratesArchives' flag in WVIEWD_WORK:
//     if the station generates archive records (TRUE) or they should be
//     generated automatically by the daemon from the sensor readings (FALSE)
//   - Initialize the 'stationData' store for station work area
//   - Initialize the interface medium
//   - do initial LOOP acquisition
//   - do any catch-up on archive records if there is a data logger
//   - 'work->runningFlag' can be used for start up synchronization but should
//     not be modified by the station interface code
//   - indicate init is done by sending the STATION_INIT_COMPLETE_EVENT event to
//     this process (radProcessEventsSend (NULL, STATION_INIT_COMPLETE_EVENT, 0))
//
// OPTIONAL:
//   - Initialize a state machine or any other construct required for the
//     station interface - these should be stored in the 'stationData' store
//
// 'archiveIndication' - indication callback used to pass back an archive record
//   generated as a result of 'stationGetArchive' being called; should receive a
//   NULL pointer for 'newRecord' if no record available; only used if
//   'stationGeneratesArchives' flag is set to TRUE by the station interface
//
// Returns: OK or ERROR
//
int stationInit
(
    WVIEWD_WORK     *work,
    void            (*archiveIndication)(ARCHIVE_PKT* newRecord)
)
{
    int             i;
    time_t          nowTime = time(NULL) - (WV_SECONDS_IN_HOUR * 12);
    ARCHIVE_PKT     recordStore;
    ARCHIVE_PKT     newestRecord;
    char            tempStr[WVIEW_MAX_PATH];

    memset (&virtualWorkData, 0, sizeof(virtualWorkData));

    // save the archive indication callback (we should never need it)
    ArchiveIndicator = archiveIndication;

    // set our work data pointer
    work->stationData = &virtualWorkData;

    // set the Archive Generation flag to indicate the VIRTUAL DOES NOT
    // generate them
    work->stationGeneratesArchives = TRUE;

    // initialize the medium abstraction based on user configuration
    if (!strcmp (work->stationInterface, "serial"))
    {
        radMsgLog (PRI_HIGH, "stationInit: serial medium not supported for virtual station!");
        return ERROR;
    }
    else if (!strcmp (work->stationInterface, "ethernet"))
    {
        if (ethernetMediumInit (&work->medium, work->stationHost, work->stationPort)
            == ERROR)
        {
            radMsgLog (PRI_HIGH, "stationInit: ethernet MediumInit failed");
            return ERROR;
        }
    }
    else
    {
        radMsgLog (PRI_HIGH, "stationInit: medium %s not supported",
                   work->stationInterface);
        return ERROR;
    }

    // initialize the interface using the media specific routine
    if ((*(work->medium.init))(&work->medium, work->stationDevice) == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: medium setup failed");
        return ERROR;
    }

    // Make the socket blocking:
    radSocketSetBlocking ((*(work->medium.getsocket))(&work->medium), TRUE);

    // Reset the stationType to include the host:port:
    sprintf(tempStr, "%s:%s:%d", 
            work->stationType, work->stationHost, work->stationPort);
    wvstrncpy(work->stationType, tempStr, sizeof(work->stationType));

    if (!strcmp (work->stationInterface, "ethernet"))
    {
        radMsgLog (PRI_STATUS, "VIRTUAL on %s:%d opened ...",
                   work->stationHost, work->stationPort);
    }

    // grab the station configuration now
    if (stationGetConfigValueInt (work,
                                  STATION_PARM_ELEVATION,
                                  &virtualWorkData.elevation)
            == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt ELEV failed!");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (stationGetConfigValueFloat (work,
                                    STATION_PARM_LATITUDE,
                                    &virtualWorkData.latitude)
            == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt LAT failed!");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (stationGetConfigValueFloat (work,
                                    STATION_PARM_LONGITUDE,
                                    &virtualWorkData.longitude)
            == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt LONG failed!");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (stationGetConfigValueInt (work,
                                  STATION_PARM_ARC_INTERVAL,
                                  &virtualWorkData.archiveInterval)
            == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt ARCINT failed!");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }

    // set the work archive interval now
    work->archiveInterval = virtualWorkData.archiveInterval;

    // sanity check the archive interval against the most recent record
    if (stationVerifyArchiveInterval (work) == ERROR)
    {
        // bad magic!
        radMsgLog (PRI_HIGH, "stationInit: stationVerifyArchiveInterval failed!");
        radMsgLog (PRI_HIGH, "You must either move old archive data out of the way -or-");
        radMsgLog (PRI_HIGH, "fix the interval setting...");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    else
    {
        radMsgLog (PRI_STATUS, "station archive interval: %d minutes",
                   work->archiveInterval);
    }

    radMsgLog (PRI_STATUS, "Starting station interface: VIRTUAL"); 

    // This must be done here:
    work->archiveDateTime = dbsqliteArchiveGetNewestTime(&newestRecord);
    if ((int)work->archiveDateTime == ERROR)
    {
        work->archiveDateTime = 0;
        radMsgLog (PRI_STATUS, "stationInit: no archive records found in database!");
    }

    // initialize the station interface
    if (virtualProtocolInit(work) == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: virtualProtocolInit failed!");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }

    // do the initial GetReadings now
    if (virtualProtocolGetReadings(work, &virtualWorkData.virtualReadings) != OK)
    {
        radMsgLog (PRI_HIGH, "stationInit: initial virtualProtocolGetReadings failed!");
        virtualProtocolExit (work);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }

    // populate the LOOP structure
    storeLoopPkt (&work->loopPkt, &virtualWorkData);

    // we must indicate successful completion here -
    // even though we are synchronous, the daemon wants to see this event
    radProcessEventsSend(NULL, STATION_INIT_COMPLETE_EVENT, 0);

    return OK;
}
Ejemplo n.º 8
0
Archivo: procmon.c Proyecto: breu/wview
//  the main entry point for the wvpmond process
int main (int argc, char *argv[])
{
    void            (*alarmHandler)(int);
    int             i, retVal, intValue, iValue;
    FILE            *pidfile, *markerFile;
    struct stat     fileStatus;
    char*           subString;
    char            markerPath[PMON_MAX_PATH], markerVal[32];
    int             runAsDaemon = TRUE;

    if (argc > 1)
    {
        if (!strcmp(argv[1], "-f"))
        {
            runAsDaemon = FALSE;
        }
    }

    memset (&procmonWork, 0, sizeof (procmonWork));

    //  initialize some system stuff first
    retVal = procmonSysInit (&procmonWork);
    if (retVal == ERROR)
    {
        radMsgLogInit (PROC_NAME_PMON, FALSE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "wvpmond init failed!\n");
        radMsgLogExit ();
        exit (1);
    }
    else if (retVal == ERROR_ABORT)
    {
        exit (2);
    }


    //  call the global radlib system init function
    if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR)
    {
        radMsgLogInit (PROC_NAME_PMON, TRUE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!");
        radMsgLogExit ();
        exit (1);
    }


    //  call the radlib process init function
    if (radProcessInit (PROC_NAME_PMON,
                        procmonWork.fifoFile,
                        PROC_NUM_TIMERS_PMON,
                        runAsDaemon,                    // TRUE for daemon
                        msgHandler,
                        evtHandler,
                        NULL)
            == ERROR)
    {
        printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_PMON);
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    procmonWork.myPid = getpid ();
    pidfile = fopen (procmonWork.pidFile, "w");
    if (pidfile == NULL)
    {
        radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n");
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    fprintf (pidfile, "%d", getpid ());
    fclose (pidfile);


    alarmHandler = radProcessSignalGetHandler (SIGALRM);
    radProcessSignalCatchAll (defaultSigHandler);
    radProcessSignalCatch (SIGALRM, alarmHandler);
    radProcessSignalRelease(SIGABRT);

    if (wvconfigInit(FALSE) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!\n");
        radMsgRouterExit ();
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // Is the procmon daemon enabled?
    iValue = wvconfigGetBooleanValue(configItem_ENABLE_PROCMON);
    if (iValue == ERROR || iValue == 0)
    {
        radMsgLog (PRI_CATASTROPHIC, "process monitor daemon is disabled - exiting...");
        wvconfigExit ();
        radMsgRouterExit ();
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // Close here; we'll re-open after waiting for the wviewd daemon to be ready:
    wvconfigExit();

    if (statusInit(procmonWork.statusFile, pmonStatusLabels) == ERROR)
    {
        radMsgLog (PRI_HIGH, "statusInit failed - exiting...");
        wvconfigExit ();
        radMsgRouterExit ();
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    statusUpdate(STATUS_BOOTING);

    //  register with the radlib message router
    if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR)
    {
        radMsgLog (PRI_HIGH, "radMsgRouterInit failed!");
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // enable message reception from the radlib router for SHUTDOWN msgs
    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_SHUTDOWN);

    // wait for the wview daemon to be ready
    if (waitForWviewDaemon () == ERROR)
    {
        radMsgLog (PRI_HIGH, "waitForWviewDaemon failed");
        statusUpdate(STATUS_ERROR);
        radMsgRouterExit ();
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    procmonWork.pollTimer = radProcessTimerCreate (NULL, pollTimerHandler, NULL);
    if (procmonWork.pollTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    procmonWork.tickTimer = radProcessTimerCreate (NULL, tickTimerHandler, NULL);
    if (procmonWork.tickTimer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed");
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    if (wvconfigInit(FALSE) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!\n");
        statusUpdateMessage("wvconfigInit failed");
        statusUpdate(STATUS_ERROR);
        radMsgRouterExit ();
        procmonSysExit (&procmonWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    // Populate our process table:
    memset (procmonWork.process, 0, sizeof(PMON_PROCESS) * PMON_PROCESS_MAX);
    for (i = 0; i < PMON_PROCESS_MAX; i ++)
    {
        iValue = wvconfigGetINTValue(configIDs[i]);
        if (iValue < 0)
        {
            // we can't do without this!
            radMsgLog (PRI_CATASTROPHIC, "PMON: %s: failed!", configIDs[i]);
            statusUpdateMessage("wvconfigGetINTValue failed");
            statusUpdate(STATUS_ERROR);
            wvconfigExit();
            radMsgRouterExit ();
            procmonSysExit (&procmonWork);
            radProcessExit ();
            radSystemExit (WVIEW_SYSTEM_ID);
            exit (1);
        }
        else
        {
            procmonWork.process[i].timeout = iValue;
            radMsgLog (PRI_STATUS, "PMON: %s: %d",
                       procNames[i], procmonWork.process[i].timeout);
        }

        if (procmonWork.process[i].timeout <= 0)
        {
            radMsgLog (PRI_STATUS, "PMON: %s process monitoring is disabled",
                       procNames[i]);
            procmonWork.process[i].ticks = -1;
            procmonWork.process[i].pid = -1;
        }
        else
        {
            // Populate the rest of the values:
            wvstrncpy (procmonWork.process[i].binFile, argv[0], PMON_MAX_PATH);
            subString = strstr (procmonWork.process[i].binFile, "wvpmond");
            if (subString == NULL)
            {
                radMsgLog (PRI_CATASTROPHIC, "PMON: %s is invalid for bin path!",
                           procmonWork.process[i].binFile);
                statusUpdateMessage("invalid for bin path");
                statusUpdate(STATUS_ERROR);
                wvconfigExit();
                radMsgRouterExit ();
                procmonSysExit (&procmonWork);
                radProcessExit ();
                radSystemExit (WVIEW_SYSTEM_ID);
                exit (1);
            }

            if (! strcmp(procNames[i], "wviewd"))
            {
                // Get the process name from the marker file:
                sprintf(markerPath, "%s/wview-binary", WVIEW_CONFIG_DIR);
                if (stat (markerPath, &fileStatus) != 0)
                {
                    radMsgLog (PRI_HIGH, "PMON: wview-binary file is missing - was 'make install' run?");
                    statusUpdateMessage("wview-binary file is missing");
                    statusUpdate(STATUS_ERROR);
                    radMsgRouterExit ();
                    procmonSysExit (&procmonWork);
                    radProcessExit ();
                    radSystemExit (WVIEW_SYSTEM_ID);
                    exit (1);
                }

                markerFile = fopen(markerPath, "r");
                if (markerFile == NULL)
                {
                    radMsgLog (PRI_HIGH, "PMON: failed to open wview-binary file - was 'make install' run?");
                    statusUpdateMessage("failed to open wview-binary file");
                    statusUpdate(STATUS_ERROR);
                    radMsgRouterExit ();
                    procmonSysExit (&procmonWork);
                    radProcessExit ();
                    radSystemExit (WVIEW_SYSTEM_ID);
                    exit (1);
                }
                if (fgets(markerVal, 32, markerFile) == NULL)
                {
                    radMsgLog (PRI_HIGH, "PMON: failed to read wview-binary file - was 'make install' run?");
                    statusUpdateMessage("failed to read wview-binary file");
                    statusUpdate(STATUS_ERROR);
                    fclose(markerFile);
                    radMsgRouterExit ();
                    procmonSysExit (&procmonWork);
                    radProcessExit ();
                    radSystemExit (WVIEW_SYSTEM_ID);
                    exit (1);
                }

                // Strip off CR/LF (caused by hand-editing of file!):
                stripEOLValues(markerVal);
                sprintf(subString, "%s", markerVal);
                fclose(markerFile);
            }
            else
            {
                sprintf (subString, "%s", procNames[i]);
            }

            sprintf (procmonWork.process[i].pidFile, "%s/%s.pid",
                     WVIEW_RUN_DIR, procNames[i]);
            if (stat (procmonWork.process[i].pidFile, &fileStatus) == -1)
            {
                // Process is not running, mark it invalid
                radMsgLog (PRI_STATUS, "PMON: pid file %s not present, disable monitoring...",
                           procmonWork.process[i].pidFile);
                procmonWork.process[i].timeout = 0;
                procmonWork.process[i].ticks = -1;
                procmonWork.process[i].pid = -1;
            }
            else
            {
                // Get his pid from the pidfile
                procmonWork.process[i].pid = pmonGetProcessPid (procmonWork.process[i].pidFile);
                if (procmonWork.process[i].pid == ERROR)
                {
                    radMsgLog (PRI_CATASTROPHIC, "PMON: failed to READ %s!",
                               procmonWork.process[i].pidFile);
                    statusUpdateMessage("failed to read pid file");
                    statusUpdate(STATUS_ERROR);
                    wvconfigExit();
                    radMsgRouterExit ();
                    procmonSysExit (&procmonWork);
                    radProcessExit ();
                    radSystemExit (WVIEW_SYSTEM_ID);
                    exit (1);
                }
            }

            // Setup the state machine
            procmonWork.process[i].stateMachine = radStatesInit (&procmonWork);
            radStatesAddHandler (procmonWork.process[i].stateMachine,
                                 PMON_STATE_IDLE,
                                 IdleStateHandler);
            radStatesAddHandler (procmonWork.process[i].stateMachine,
                                 PMON_STATE_WAIT_RESP,
                                 WaitRespStateHandler);
            radStatesAddHandler (procmonWork.process[i].stateMachine,
                                 PMON_STATE_WAIT_EXIT,
                                 WaitExitStateHandler);
            radStatesAddHandler (procmonWork.process[i].stateMachine,
                                 PMON_STATE_WAIT_START,
                                 WaitStartStateHandler);
            radStatesSetState (procmonWork.process[i].stateMachine, PMON_STATE_IDLE);
        }
    }

    wvconfigExit();


    radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL_RESPONSE);

    // Start the timers:
    radProcessTimerStart (procmonWork.pollTimer, PMON_POLL_INTERVAL);
    radProcessTimerStart (procmonWork.tickTimer, PMON_TICK_INTERVAL);


    // enter normal processing
    procmonWork.inMainLoop = TRUE;
    statusUpdate(STATUS_RUNNING);
    statusUpdateMessage("Normal operation");
    radMsgLog (PRI_STATUS, "running...");

    while (!procmonWork.exiting)
    {
        // wait on something interesting
        if (radProcessWait (0) == ERROR)
        {
            procmonWork.exiting = TRUE;
        }
    }


    statusUpdateMessage("exiting normally");
    radMsgLog (PRI_STATUS, "exiting normally...");
    statusUpdate(STATUS_SHUTDOWN);

    radMsgRouterExit ();
    radProcessTimerDelete (procmonWork.pollTimer);
    radProcessTimerDelete (procmonWork.tickTimer);
    procmonSysExit (&procmonWork);
    radProcessExit ();
    radSystemExit (WVIEW_SYSTEM_ID);
    exit (0);
}
Ejemplo n.º 9
0
void multiChartSetDateTime (MULTICHART_ID id, char *datetime)
{
    wvstrncpy (id->datetime, datetime, sizeof(id->datetime));
    return;
}
Ejemplo n.º 10
0
static void drawTitle (MULTICHART_ID id)
{
    int         i, totalLen = 0;
    char        xtitle[WVIEW_STRING1_SIZE];

    gdImageFilledRectangle (id->im,
                            0, 0,
                            id->width, gdFontMediumBold->h,
                            id->titleBGcolor);

    if (strlen(id->DualUnit) != 0)
    {
        wvstrncpy (xtitle, id->title, sizeof(xtitle));
        if ((strcmp(id->title,"knots") == 0) || (strcmp(id->title,"m/s") == 0))
        {
            if (id->isMetric)
            {
                strcpy (xtitle, "km/h");
            }
            else
            {
                strcpy (xtitle, "mph");
            }
        }

        for (i = 0; i < id->numdatasets; i ++)
        {
            totalLen += 2;
            totalLen += (((gdFontMediumBold->h/2)+2) * strlen (id->dataset[i].legend));
        }
        totalLen = (id->width - totalLen) - 3;
        totalLen /= 2;

        // totalLen = (((gdFontMediumBold->h/2)+2) * strlen (xtitle))+2;
        for (i = 0; i < id->numdatasets; i ++)
        {
            totalLen += 2;
            gdImageString (id->im,
                           gdFontMediumBold,
                           totalLen,
                           0,
                           (UCHAR *)id->dataset[i].legend,
                           id->dataset[i].lineColor);

            totalLen += (((gdFontMediumBold->h/2)+2) * strlen (id->dataset[i].legend));
        }

        gdImageString (id->im,
                       gdFontMediumBold,
                       id->width - (((gdFontMediumBold->h/2)+2) * strlen (id->DualUnit)),
                       0,
                       (UCHAR *)id->DualUnit,
                       id->titleFGcolor);

        gdImageString (id->im,
                       gdFontMediumBold,
                       2,
                       0,
                       (UCHAR *)xtitle,
                       id->titleFGcolor);
    }
    else
    {
        for (i = 0; i < id->numdatasets; i ++)
        {
            totalLen += 2;
            gdImageString (id->im,
                           gdFontMediumBold,
                           totalLen,
                           0,
                           (UCHAR *)id->dataset[i].legend,
                           id->dataset[i].lineColor);

            totalLen += (((gdFontMediumBold->h/2)+2) * strlen (id->dataset[i].legend));
        }

        gdImageString (id->im,
                       gdFontMediumBold,
                       id->width - (((gdFontMediumBold->h/2)+2) * strlen (id->title)),
                       0,
                       (UCHAR *)id->title,
                       id->titleFGcolor);

    }
}
Ejemplo n.º 11
0
int htmlStationInfoState (int state, void *stimulus, void *data)
{
    STIM                        *stim = (STIM *)stimulus;
    HTML_WORK                   *work = (HTML_WORK *)data;
    int                         seconds;
    WVIEW_MSG_STATION_INFO      *msg = (WVIEW_MSG_STATION_INFO *)stim->msg;
    time_t                      ntime;
    struct tm                   locTime;
    long                        offset, msOffset;
    long                        oldSecs, newSecs;
    int                         currDay, currMonth, currYear;
    float                       gmtOffsetHours;
    int16_t                     tempShort;
    FILE*                       indicateFile;

    ntime = time (NULL);
    localtime_r (&ntime, &locTime);
    currDay     = locTime.tm_mday;
    currMonth   = locTime.tm_mon + 1;
    currYear    = locTime.tm_year + 1900;
#ifdef HAVE_TM_GMTOFF
    gmtOffsetHours = locTime.tm_gmtoff/(60.0*60.0);
#else
    gmtOffsetHours = gmtoffset()/(60.0*60.0);    
#endif

    switch (stim->type)
    {
    case STIM_QMSG:
        if (stim->msgType == WVIEW_MSG_TYPE_STATION_INFO)
        {
            radMsgRouterMessageDeregister(WVIEW_MSG_TYPE_STATION_INFO);
            ntime = msg->lastArcTime;
            localtime_r (&ntime, &locTime);
            radMsgLog (PRI_STATUS, 
                       "received station info from wviewd: "
                       "%4.4d%2.2d%2.2d %2.2d:%2.2d:%2.2d",
                       locTime.tm_year + 1900,
                       locTime.tm_mon + 1,
                       locTime.tm_mday,
                       locTime.tm_hour,
                       locTime.tm_min,
                       locTime.tm_sec);

            work->archiveInterval = msg->archiveInterval;
            
            // Initialize the archive database interface:
            if (dbsqliteArchiveInit() == ERROR)
            {
                radMsgLog (PRI_HIGH, "dbsqliteArchiveInit failed");
                statusUpdateMessage("dbsqliteArchiveInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initialize the htmlMgr now that we know the archive interval:
            work->mgrId = htmlmgrInit (WVIEW_CONFIG_DIR, 
                                       work->isMetricUnits,
                                       work->imagePath,
                                       work->htmlPath,
                                       work->archiveInterval,
                                       work->isExtendedData,
                                       work->stationName,
                                       work->stationCity,
                                       work->stationState,
                                       msg->elevation,
                                       msg->latitude,
                                       msg->longitude,
                                       work->mphaseIncrease,
                                       work->mphaseDecrease,
                                       work->mphaseFull,
                                       work->radarURL,
                                       work->forecastURL,
                                       work->dateFormat,
                                       work->isDualUnits);
            if (work->mgrId == NULL)
            {
                radMsgLog (PRI_HIGH, "htlmgrInit failed!");
                statusUpdateMessage("htlmgrInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }
        
            wvstrncpy (work->mgrId->stationType,
                       msg->stationType,
                       sizeof(work->mgrId->stationType));

            //  ... initialize the sun times now
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_SUN,
                                   &work->mgrId->sunrise,
                                   &work->mgrId->sunset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_CIVIL,
                                   &work->mgrId->civilrise,
                                   &work->mgrId->civilset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_ASTRO,
                                   &work->mgrId->astrorise,
                                   &work->mgrId->astroset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_MIDDAY,
                                   &work->mgrId->midday,
                                   &tempShort);
            work->mgrId->dayLength = 
                    sunTimesGetDayLength (currYear, currMonth, currDay,
                                          (float)work->mgrId->stationLatitude/10,
                                          (float)work->mgrId->stationLongitude/10);

            GetMoonRiseSetTimes (currYear, currMonth, currDay,
                                 (float)gmtOffsetHours,
                                 (float)work->mgrId->stationLatitude/10,
                                 (float)work->mgrId->stationLongitude/10,
                                 &work->mgrId->moonrise,
                                 NULL,
                                 &work->mgrId->moonset,
                                 NULL);



            //  ... initialize the barometric pressure trend algorithm:
            radMsgLog (PRI_STATUS, "initializing barometric pressure trend");        
            if (htmlmgrBPTrendInit (work->mgrId, work->timerInterval/60000)
                == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlmgrBPTrendInit failed!");
                statusUpdateMessage("htmlmgrBPTrendInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

           
            //  ... load up our historical stores for the history charts:
            radMsgLog (PRI_STATUS, "initializing historical stores (this may take some time...)");  
            if (htmlmgrHistoryInit (work->mgrId) == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlStationInfoState: htmlmgrHistoryInit failed!");
                statusUpdateMessage("htmlmgrHistoryInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // store the "last" values
            ntime = time(NULL);
            localtime_r (&ntime, &locTime);
            work->histLastHour = locTime.tm_hour;
            work->histLastDay = locTime.tm_mday;

            
            // Initialize the HILOW database interface:
            // (this cannot occur before wviewd sends us the archive time)
            if (dbsqliteHiLowInit(FALSE) == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "dbsqliteHiLowInit failed!");
                statusUpdateMessage("dbsqliteHiLowInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // initialize the NOAA database:
            if (dbsqliteNOAAInit() == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "dbsqliteNOAAInit failed!");
                statusUpdateMessage("dbsqliteNOAAInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // initialize the NOAA report generator
            radMsgLog (PRI_STATUS, "NOAA: initializing reports (this may take some time...)");  
            work->noaaId = noaaGenerateInit (work->mgrId->imagePath,
                                             work->isMetricUnits,
                                             msg->latitude,
                                             msg->longitude,
                                             msg->elevation,
                                             work->stationName,
                                             work->stationCity,
                                             work->stationState,
                                             msg->lastArcTime);
            if (work->noaaId == NULL)
            {
                radMsgLog (PRI_CATASTROPHIC, "noaaGenerateInit failed!");
                statusUpdateMessage("noaaGenerateInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initialize the archive record browser generator
            radMsgLog (PRI_STATUS, "ARCREC: initializing archive browser files (this may take some time...)");  
            if (arcrecGenerateInit (work->mgrId->imagePath,
                                    work->arcrecDaysToKeep,
                                    work->isMetricUnits,
                                    work->archiveInterval)
                == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "arcrecGenerateInit failed!");
                statusUpdateMessage("arcrecGenerateInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initial data request then start the data acquisition timer
            if (requestDataPackets (work) == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlStationInfoState: requestDataPackets failed!");
                statusUpdateMessage("requestDataPackets failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            radProcessTimerStart (work->rxTimer, HTML_RX_PACKETS_TIMEOUT);

            // wait here until a new second arrives
            ntime = time (NULL);
            localtime_r (&ntime, &locTime);
            oldSecs = newSecs = locTime.tm_sec;
            while (oldSecs == newSecs)
            {
                ntime = time (NULL);
                localtime_r (&ntime, &locTime);
                newSecs = locTime.tm_sec;
            }
            
            
            /*  ... start the data timer to go off at the next 5 minute
                ... interval plus the user offset
            */
            ntime = time (NULL);
            localtime_r (&ntime, &locTime);
            seconds = locTime.tm_sec - 10L;         // start at 10 secs past

            offset = locTime.tm_min % 5L;           // where are we in period?
            offset = 5 - offset;                    // how many mins to get to "0"?
            offset %= 5;                            // don't want "5"
            offset += work->startOffset;            // user start in period
            if (offset == 0L)                       // prevent negative timeout
                seconds -= 60L;                     // make neg so timeout is pos

            if (seconds < -60L)
            {
                offset += 1L;
                seconds += 60L;
            }

            radMsgLog (PRI_STATUS,
                       "starting html generation in %d mins %d secs",
                       ((seconds > 0L) ? ((offset > 0L) ? offset - 1L : offset) : offset),
                               (seconds > 0L) ? 60L - seconds : (-1L) * seconds);

            work->nextGenerationTime.tv_sec = (long)ntime + ((offset * 60L) - seconds);
            work->nextGenerationTime.tv_usec = 250L * 1000L;
            
            msOffset = 250L;                        // land on 250 ms mark

            radProcessTimerStart (work->timer,
                                  ((((offset * 60L) - seconds) * 1000L)) + msOffset);


            // 20041224 - Add an immediate generation cycle so longer 
            // duration archive intervals don't have to wait up to 30 minutes
            // for the first generation
            radMsgLog (PRI_STATUS, "doing initial html generation now...");
            work->numDataReceived = 0;

            statusUpdate(STATUS_RUNNING);
            statusUpdateMessage("Normal operation");

            // Save an indicator in the run directory so web apps know when we are up:
            indicateFile = fopen (work->indicateFile, "w");
            if (indicateFile == NULL)
            {
                radMsgLog (PRI_CATASTROPHIC, "indicator file create failed!");
                statusUpdateMessage("indicator file create failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }
            fprintf (indicateFile, "%d", (int)msg->lastArcTime);
            fclose (indicateFile);

            return HTML_STATE_DATA;
        }

        break;
    }

    return state;
}
Ejemplo n.º 12
0
static int readImageConfFile (HTML_MGR *mgr, char *filename, int isUser)
{
    HTML_IMG        *img;
    FILE            *file;
    int             i, done;
    char            *token;
    char            temp[1536];

    file = fopen (filename, "r");
    if (file == NULL)
    {
        radMsgLog (PRI_HIGH, "htmlmgrInit: %s does not exist!",
                   filename);
        return ERROR_ABORT;
    }

    while (fgets (temp, 1536, file) != NULL)
    {
        if (temp[0] == ' ' || temp[0] == '\n' || temp[0] == '#')
        {
            // comment or whitespace
            continue;
        }

        token = strtok (temp, " \t");
        if (token == NULL)
        {
            continue;
        }

        img = (HTML_IMG *)malloc (sizeof (*img));
        if (img == NULL)
        {
            for (img = (HTML_IMG *)radListRemoveFirst (&mgr->imgList);
                    img != NULL;
                    img = (HTML_IMG *)radListRemoveFirst (&mgr->imgList))
            {
                free (img);
            }

            fclose (file);
            return ERROR;
        }
        memset (img, 0, sizeof (*img));

        img->mgrWork    = mgr;
        
        
        //  ... if legacy image type is found, skip it
        if (!strncmp (token, "IMG_TYPE_", 9))
        {
            // get the next token
            token = strtok (NULL, " \t");
            if (token == NULL)
            {
                free (img);
                goto line_loop_end;
            }
        }

        //  ... do the file name
        wvstrncpy (img->fname, token, sizeof(img->fname));

        //  ... now the label
        token = strtok (NULL, " \t");
        if (token == NULL)
        {
            free (img);
            goto line_loop_end;
        }
        if (token[strlen(token)-1] == '"')
        {
            // we're done!
            strncpy (img->title, &token[1], strlen(token)-2);   // lose quotes
        }
        else
        {
            done = FALSE;
            wvstrncpy (img->title, &token[1], sizeof(img->title));
            while (!done)
            {
                token = strtok (NULL, " ");
                if (token == NULL)
                {
                    free(img);
                    goto line_loop_end;
                }
                else
                {
                    if (token[strlen(token)-1] == '"')
                    {
                        done = TRUE;
                        token[strlen(token)-1] = 0;
                    }
                    strcat (img->title, " ");
                    strcat (img->title, token);
                }
            }
        }

        //  ... now the units label (no spaces allowed)
        token = strtok (NULL, " \t");
        if (token == NULL)
        {
            free (img);
            goto line_loop_end;
        }
        wvstrncpy (img->units, token, sizeof(img->units));

        //  ... now the decimal places
        token = strtok (NULL, " \t");
        if (token == NULL)
        {
            free (img);
            goto line_loop_end;
        }
        img->decimalPlaces = atoi (token);

        //  ... finally, the generator index
        token = strtok (NULL, " \t\n");
        if (token == NULL)
        {
            free (img);
            goto line_loop_end;
        }
        i = atoi (token);
        if (isUser)
        {
            img->generator = user_generators[i];
        }
        else
        {
            img->generator = images_generators[i];
        }

        radListAddToEnd (&mgr->imgList, (NODE_PTR)img);

// Loop end label:
line_loop_end:
        continue;
    }

    fclose (file);
    return OK;
}
Ejemplo n.º 13
0
HTML_MGR_ID htmlmgrInit
(
    char            *installPath,
    int             isMetricUnits,
    char            *imagePath,
    char            *htmlPath,
    int             arcInterval,
    int             isExtendedData,
    char            *name,
    char            *city,
    char            *state,
    int16_t         elevation,
    int16_t         latitude,
    int16_t         longitude,
    char            *mphaseIncrease,
    char            *mphaseDecrease,
    char            *mphaseFull,
    char            *radarURL,
    char            *forecastURL,
    char            *dateFormat,
    int             isDualUnits
)
{
    HTML_MGR_ID     newId;
    int             i, numNodes, numImages, numTemplates;
    char            confFilePath[256];

    newId = &mgrWork;
    memset (newId, 0, sizeof (mgrWork));

    radListReset (&newId->imgList);
    radListReset (&newId->templateList);
    
    newId->isMetricUnits    = isMetricUnits;
    newId->archiveInterval  = arcInterval;
    newId->isExtendedData   = isExtendedData;
    newId->imagePath        = imagePath;
    newId->htmlPath         = htmlPath;
    newId->stationElevation = elevation;
    newId->stationLatitude  = latitude;
    newId->stationLongitude = longitude;
    wvstrncpy (newId->stationName, name, sizeof(newId->stationName));
    wvstrncpy (newId->stationCity, city, sizeof(newId->stationCity));
    wvstrncpy (newId->stationState, state, sizeof(newId->stationState));
    wvstrncpy (newId->mphaseIncrease, mphaseIncrease, sizeof(newId->mphaseIncrease));
    wvstrncpy (newId->mphaseDecrease, mphaseDecrease, sizeof(newId->mphaseDecrease));
    wvstrncpy (newId->mphaseFull, mphaseFull, sizeof(newId->mphaseFull));
    wvstrncpy (newId->radarURL, radarURL, sizeof(newId->radarURL));
    wvstrncpy (newId->forecastURL, forecastURL, sizeof(newId->forecastURL));
    wvstrncpy (newId->dateFormat, dateFormat, sizeof(newId->dateFormat));
    newId->isDualUnits    = isDualUnits;
    
    //  ... initialize the newArchiveMask
    newId->newArchiveMask = NEW_ARCHIVE_ALL;

    
    //  ... first, the built-in generators
    sprintf (confFilePath, "%s/images.conf", installPath);
    if (readImageConfFile (newId, confFilePath, FALSE) != OK)
    {
        return NULL;
    }
    else
    {
        numNodes = radListGetNumberOfNodes (&newId->imgList);
        radMsgLog (PRI_STATUS, "htmlmgrInit: %d built-in image definitions added",
                   numNodes);
        numImages = numNodes;
    }

    //  ... next, the user-defined generators
    sprintf (confFilePath, "%s/images-user.conf", installPath);
    i = readImageConfFile (newId, confFilePath, TRUE);
    if (i == ERROR_ABORT)
    {
        radMsgLog (PRI_STATUS, "htmlmgrInit: no user image definitions found");
    }
    else if (i == ERROR)
    {
        return NULL;
    }
    else
    {
        numImages = radListGetNumberOfNodes (&newId->imgList);
        radMsgLog (PRI_STATUS, "htmlmgrInit: %d user image definitions added",
                   radListGetNumberOfNodes (&newId->imgList) - numNodes);
    }

    //  ... now initialize our html template list
    sprintf (confFilePath, "%s/html-templates.conf", installPath);
    if (readHtmlTemplateFile (newId, confFilePath) != OK)
    {
        return NULL;
    }
    else
    {
        numTemplates = radListGetNumberOfNodes (&newId->templateList);
        radMsgLog (PRI_STATUS, "htmlmgrInit: %d templates added", numTemplates);
    }

    //  ... now initialize our forecast rule text list
    sprintf (confFilePath, "%s/forecast.conf", installPath);
    if (readForecastRuleConfigFile (newId, confFilePath) != OK)
    {
        radMsgLog (PRI_STATUS, "htmlmgrInit: forecast html tags are disabled - %s not found...",
                   confFilePath);
    }

    //  ... initialize the sample label array
    htmlmgrSetSampleLabels(newId);

    //  ... initialize our dial palette to conserve CPU cycles
    if (htmlGenPngDialInit (newId->imagePath) == ERROR)
    {
        radMsgLog (PRI_HIGH, "htmlmgrInit: htmlGenPngDialInit failed!");
        return NULL;
    }

    statusUpdateStat(HTML_STATS_IMAGES_DEFINED, numImages);
    statusUpdateStat(HTML_STATS_TEMPLATES_DEFINED, numTemplates);

    return newId;
}
Ejemplo n.º 14
0
static int readForecastRuleConfigFile (HTML_MGR *mgr, char *filename)
{
    FILE            *file;
    char            *token;
    char            temp[HTML_MAX_LINE_LENGTH];
    int             iconNo = 1, ruleNo = 0;

    file = fopen (filename, "r");
    if (file == NULL)
    {
        return ERROR_ABORT;
    }

    //  read each line starting with "ICON", assigning to the corresponding 
    //  forecast icon
    while (fgets (temp, HTML_MAX_LINE_LENGTH-1, file) != NULL)
    {
        // does the line begin with "ICON"?
        if (strncmp (temp, "ICON", 4))
        {
            // nope
            continue;
        }
        
        // get the memory to store the string
        mgr->ForecastIconFile[iconNo] = (char *) malloc (FORECAST_ICON_FN_MAX);
        if (mgr->ForecastIconFile[iconNo] == NULL)
        {
            radMsgLog (PRI_HIGH, 
                       "readForecastRuleConfigFile: cannot allocate memory for forecast icon #%d!",
                       iconNo);
            cleanupForecastRules (mgr);
            fclose(file);
            return ERROR;
        }
        
        // skip the ICON keyword
        token = strtok (temp, " \t");
        if (token == NULL)
        {
            free (mgr->ForecastIconFile[iconNo]);
            mgr->ForecastIconFile[iconNo] = NULL;
            continue;
        }
        token = strtok (NULL, " \t\n");
        if (token == NULL)
        {
            free (mgr->ForecastIconFile[iconNo]);
            mgr->ForecastIconFile[iconNo] = NULL;
            continue;
        }

        wvstrncpy (mgr->ForecastIconFile[iconNo], 
                   token, 
                   FORECAST_ICON_FN_MAX);
        if (mgr->ForecastIconFile[iconNo][strlen(mgr->ForecastIconFile[iconNo]) - 1] == '\n')
            mgr->ForecastIconFile[iconNo][strlen(mgr->ForecastIconFile[iconNo]) - 1] = 0;
        
        if (++iconNo == (VP_FCAST_ICON_MAX + 1))
        {
            // we're done!
            break;
        }
    }

    
    // reset to the beginning of the file
    fseek (file, 0, SEEK_SET);
    

    // throw away all lines until we hit the keyword "RULES"
    while (fgets (temp, HTML_MAX_LINE_LENGTH-1, file) != NULL)
    {
        if (!strncmp (temp, "<RULES>", 7))
        {
            // begin the rule dance
            break;
        }
    }

    //  read each line, assigning to the corresponding forecast rule
    while (fgets (temp, HTML_MAX_LINE_LENGTH-1, file) != NULL)
    {
        // get the memory to store the string
        mgr->ForecastRuleText[ruleNo] = (char *) malloc (strlen(temp) + 1);
        if (mgr->ForecastRuleText[ruleNo] == NULL)
        {
            radMsgLog (PRI_HIGH, "readForecastRuleConfigFile: cannot allocate memory for forecast rule #%d!",
                       ruleNo);
            cleanupForecastRules (mgr);
            fclose(file);
            return ERROR;
        }
        
        // copy the string (we know temp is bounded and we allocated for its length):
        strcpy (mgr->ForecastRuleText[ruleNo], temp);
        if (mgr->ForecastRuleText[ruleNo][strlen(temp) - 1] == '\n')
            mgr->ForecastRuleText[ruleNo][strlen(temp) - 1] = 0;
        
        if (++ruleNo == (HTML_MAX_FCAST_RULE + 1))
        {
            // we're done!
            break;
        }
    }
    
    // did we find them all?
    if (ruleNo != (HTML_MAX_FCAST_RULE + 1))
    {
        // nope, let's fuss about it
        radMsgLog (PRI_MEDIUM, "readForecastRuleConfigFile: NOT all forecast rules are assigned in %s: "
                               "the last %d are missing and will be empty ...",
                   filename,
                   (HTML_MAX_FCAST_RULE + 1) - ruleNo);
    }
    if (iconNo != (VP_FCAST_ICON_MAX + 1))
    {
        // nope, let's fuss about it
        radMsgLog (PRI_MEDIUM, "readForecastRuleConfigFile: NOT all forecast icons are assigned in %s: "
                               "the last %d are missing and will be empty ...",
                   filename,
                   (VP_FCAST_ICON_MAX + 1) - iconNo);
    }

    radMsgLog (PRI_STATUS, "%d icon definitions, %d forecast rules found ...",
               iconNo - 1,
               ruleNo);

    fclose (file);
    return OK;
}
Ejemplo n.º 15
0
Archivo: alarms.c Proyecto: breu/wview
static int readAlarmsConfig (void)
{
    WVIEW_ALARM     *alarm;
    int             i, numAlarms = 0;
    int             iValue;
    char            type[_MAX_PATH];
    int             boolMAX;
    double          thresh;
    int             abate;
    char            exec[_MAX_PATH];
    char            conftype[64];
    const char*     temp;

    if (wvconfigInit(FALSE) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!");
        return ERROR;
    }

    // Is the alarms daemon enabled?
    iValue = wvconfigGetBooleanValue(configItem_ENABLE_ALARMS);
    if (iValue == ERROR || iValue == 0)
    {
        wvconfigExit ();
        return ERROR_ABORT;
    }

    // set the wview verbosity setting
    if (wvutilsSetVerbosity (WV_VERBOSE_WVALARMD) == ERROR)
    {
        radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!");
        wvconfigExit ();
        return ERROR_ABORT;
    }

    // get the metric units flag:
    iValue = wvconfigGetBooleanValue(configItem_ALARMS_STATION_METRIC);
    if (iValue == ERROR)
    {
        alarmsWork.isMetric = 0;
    }
    else
    {
        alarmsWork.isMetric = iValue;
    }

    // get the do test flag:
    iValue = wvconfigGetBooleanValue(configItem_ALARMS_DO_TEST);
    if (iValue <= 0)
    {
        alarmsWork.doTest = FALSE;
    }
    else
    {
        alarmsWork.doTest = TRUE;
        alarmsWork.doTestNumber = wvconfigGetINTValue(configItem_ALARMS_DO_TEST_NUMBER);
    }

    for (i = 1; i <= ALARMS_MAX; i ++)
    {
        sprintf (conftype, "ALARMS_%1.1d_TYPE", i);
        temp = wvconfigGetStringValue(conftype);
        if (temp == NULL)
        {
            // No type defined - continue:
            continue;
        }
        wvstrncpy(type, temp, _MAX_PATH);

        sprintf (conftype, "ALARMS_%1.1d_MAX", i);
        boolMAX = wvconfigGetBooleanValue(conftype);
        if (boolMAX == ERROR)
        {
            continue;
        }

        sprintf (conftype, "ALARMS_%1.1d_THRESHOLD", i);
        thresh = wvconfigGetDOUBLEValue(conftype);

        sprintf (conftype, "ALARMS_%1.1d_ABATEMENT", i);
        abate = wvconfigGetINTValue(conftype);

        sprintf (conftype, "ALARMS_%1.1d_EXECUTE", i);
        temp = wvconfigGetStringValue(conftype);
        if (temp == NULL)
        {
            // No type defined - continue:
            continue;
        }
        wvstrncpy(exec, temp, _MAX_PATH);

        alarm = (WVIEW_ALARM *) malloc (sizeof (*alarm));
        if (alarm == NULL)
        {
            for (alarm = (WVIEW_ALARM *)radListRemoveFirst (&alarmsWork.alarmList);
                 alarm != NULL;
                 alarm = (WVIEW_ALARM *)radListRemoveFirst (&alarmsWork.alarmList))
            {
                free (alarm);
            }

            return ERROR;
        }
        memset (alarm, 0, sizeof (*alarm));


        // get the type
        if (!strcmp (type, "Barometer"))
        {
            alarm->type = Barometer;
        }
        else if (!strcmp (type, "InsideTemp"))
        {
            alarm->type = InsideTemp;
        }
        else if (!strcmp (type, "InsideHumidity"))
        {
            alarm->type = InsideHumidity;
        }
        else if (!strcmp (type, "OutsideTemp"))
        {
            alarm->type = OutsideTemp;
        }
        else if (!strcmp (type, "WindSpeed"))
        {
            alarm->type = WindSpeed;
        }
        else if (!strcmp (type, "TenMinuteAvgWindSpeed"))
        {
            alarm->type = TenMinuteAvgWindSpeed;
        }
        else if (!strcmp (type, "WindDirection"))
        {
            alarm->type = WindDirection;
        }
        else if (!strcmp (type, "OutsideHumidity"))
        {
            alarm->type = OutsideHumidity;
        }
        else if (!strcmp (type, "RainRate"))
        {
            alarm->type = RainRate;
        }
        else if (!strcmp (type, "StormRain"))
        {
            alarm->type = StormRain;
        }
        else if (!strcmp (type, "DayRain"))
        {
            alarm->type = DayRain;
        }
        else if (!strcmp (type, "MonthRain"))
        {
            alarm->type = MonthRain;
        }
        else if (!strcmp (type, "YearRain"))
        {
            alarm->type = YearRain;
        }
        else if (!strcmp (type, "TxBatteryStatus"))
        {
            alarm->type = TxBatteryStatus;
        }
        else if (!strcmp (type, "ConsoleBatteryVoltage"))
        {
            alarm->type = ConsoleBatteryVoltage;
        }
        else if (!strcmp (type, "DewPoint"))
        {
            alarm->type = DewPoint;
        }
        else if (!strcmp (type, "WindChill"))
        {
            alarm->type = WindChill;
        }
        else if (!strcmp (type, "HeatIndex"))
        {
            alarm->type = HeatIndex;
        }
        else if (!strcmp (type, "Radiation"))
        {
            alarm->type = Radiation;
        }
        else if (!strcmp (type, "UV"))
        {
            alarm->type = UV;
        }
        else if (!strcmp (type, "ET"))
        {
            alarm->type = ET;
        }
        else if (!strcmp (type, "ExtraTemp1"))
        {
            alarm->type = ExtraTemp1;
        }
        else if (!strcmp (type, "ExtraTemp2"))
        {
            alarm->type = ExtraTemp2;
        }
        else if (!strcmp (type, "ExtraTemp3"))
        {
            alarm->type = ExtraTemp3;
        }
        else if (!strcmp (type, "SoilTemp1"))
        {
            alarm->type = SoilTemp1;
        }
        else if (!strcmp (type, "SoilTemp2"))
        {
            alarm->type = SoilTemp2;
        }
        else if (!strcmp (type, "SoilTemp3"))
        {
            alarm->type = SoilTemp3;
        }
        else if (!strcmp (type, "SoilTemp4"))
        {
            alarm->type = SoilTemp4;
        }
        else if (!strcmp (type, "LeafTemp1"))
        {
            alarm->type = LeafTemp1;
        }
        else if (!strcmp (type, "LeafTemp2"))
        {
            alarm->type = LeafTemp2;
        }
        else if (!strcmp (type, "ExtraHumid1"))
        {
            alarm->type = ExtraHumid1;
        }
        else if (!strcmp (type, "ExtraHumid2"))
        {
            alarm->type = ExtraHumid2;
        }
        else if (!strcmp (type, "Wxt510Hail"))
        {
            alarm->type = Wxt510Hail;
        }
        else if (!strcmp (type, "Wxt510Hailrate"))
        {
            alarm->type = Wxt510Hailrate;
        }
        else if (!strcmp (type, "Wxt510HeatingTemp"))
        {
            alarm->type = Wxt510HeatingTemp;
        }
        else if (!strcmp (type, "Wxt510HeatingVoltage"))
        {
            alarm->type = Wxt510HeatingVoltage;
        }
        else if (!strcmp (type, "Wxt510SupplyVoltage"))
        {
            alarm->type = Wxt510SupplyVoltage;
        }
        else if (!strcmp (type, "Wxt510ReferenceVoltage"))
        {
            alarm->type = Wxt510ReferenceVoltage;
        }
        else
        {
            free (alarm);
            radMsgLog (PRI_MEDIUM, "invalid alarm type %s - skipping...",
                       type);
            continue;
        }

        //  do the max/min flag
        alarm->isMax = boolMAX;

        //  now the bounding value
        alarm->bound = (float)thresh;

        //  now the abatement seconds
        alarm->abateSecs = abate;

        //  finally, the alarm script
        wvstrncpy (alarm->scriptToRun, exec, WVIEW_ALARM_SCRIPT_LENGTH);

        radListAddToEnd (&alarmsWork.alarmList, (NODE_PTR)alarm);
    }

    wvconfigExit ();
    return (radListGetNumberOfNodes (&alarmsWork.alarmList));
}