Esempio n. 1
0
File: procmon.c Progetto: breu/wview
static void tickTimerHandler (void *parm)
{
    int             i;
    PMON_STIM       stim;

    for (i = 0; i < PMON_PROCESS_MAX; i ++)
    {
        if (procmonWork.process[i].timeout <= 0 ||
                procmonWork.process[i].ticks <= 0)
        {
            // Skip this guy
            continue;
        }

        procmonWork.process[i].ticks --;
        if (procmonWork.process[i].ticks == 0)
        {
            // Tickle the state machine
            memset (&stim, 0, sizeof(stim));
            stim.index = i;
            stim.type  = PMON_STIM_TIMEOUT;
            radStatesProcess (procmonWork.process[i].stateMachine, &stim);
        }
    }

    radProcessTimerStart (procmonWork.tickTimer, PMON_TICK_INTERVAL);
    return;
}
Esempio n. 2
0
File: cwop.c Progetto: breu/wview
static void timerHandler (void *parm)
{
    time_t          ntime;
    struct tm       locTime;

    radProcessTimerStart (cwopWork.timer, CWOP_MINUTE_INTERVAL);

    ntime = time (NULL);
    localtime_r (&ntime, &locTime);

    if ((locTime.tm_min % cwopWork.reportInterval) == cwopWork.callSignOffset)
    {
        // Time to send a packet if we have any new data:
        if (cwopWork.rxArchive)
        {
            processCWOP ();
            cwopWork.rxArchive = FALSE;
        }
        else
        {
            if (cwopWork.rxFirstArchive)
            {
                statusUpdateMessage("no new archive data received since last CWOP submission");
                radMsgLog (PRI_MEDIUM, 
                    "wvcwopd: no new archive data received since last CWOP submission:");
            }
        }
    }

    return;
}
Esempio n. 3
0
File: ssh.c Progetto: psumbera/wview
static void timerHandler (void *parm)
{
    uint64_t    msOffset = radTimeGetMSSinceEpoch ();
    int64_t     netOffset;

    //  ... allow for timer latency
    if (sshWork.msOffset == 0ULL)
    {
        // first time through
        sshWork.msOffset = msOffset;
        netOffset = 0LL;
    }
    else
    {
        netOffset = msOffset - sshWork.msOffset;
    }

    sshWork.msOffset += 60000ULL;               // ALWAYS 1 minute

    radProcessTimerStart (sshWork.timer, (uint32_t)(60000LL - netOffset));


    //  ... process the ssh rules
    sshUtilsSendFiles (sshWork.sshId, sshWork.wviewdir);

    return;
}
Esempio n. 4
0
int htmlRunState (int state, void *stimulus, void *data)
{
    STIM                        *stim = (STIM *)stimulus;
    HTML_WORK                   *work = (HTML_WORK *)data;
    WVIEW_MSG_LOOP_DATA         *loop = (WVIEW_MSG_LOOP_DATA *)stim->msg;
    WVIEW_MSG_HILOW_DATA        *hilow = (WVIEW_MSG_HILOW_DATA *)stim->msg;
    WVIEW_MSG_ARCHIVE_NOTIFY    *arcNot = (WVIEW_MSG_ARCHIVE_NOTIFY *)stim->msg;

    switch (stim->type)
    {
        case STIM_QMSG:
            if (stim->msgType == WVIEW_MSG_TYPE_LOOP_DATA)
            {
                work->mgrId->loopStore = loop->loopData;
                return state;
            }
            else if (stim->msgType == WVIEW_MSG_TYPE_HILOW_DATA)
            {
                work->mgrId->hilowStore = hilow->hilowData;
                return state;
            }
            else if (stim->msgType == WVIEW_MSG_TYPE_ARCHIVE_NOTIFY)
            {
                processNewArchiveRecord (work, arcNot);
                return state;
            }

        break;

        case STIM_TIMER:
            if (stim->timerNumber == TIMER_GENERATE)
            {
                //  ... request the next batch of data
                if (requestDataPackets (work) == ERROR)
                {
                    radMsgLog (PRI_HIGH, "htmlRunState: requestDataPackets failed!");
                    statusUpdateMessage("requestDataPackets failed!");
                    statusUpdate(STATUS_ERROR);
                    return HTML_STATE_ERROR;
                }
    
                radProcessTimerStart(work->rxTimer, HTML_RX_PACKETS_TIMEOUT);
                work->numDataReceived = 0;
    
                return HTML_STATE_DATA;
            }
    
            return state;
        }

    return state;
}
Esempio n. 5
0
File: ftp.c Progetto: breu/wview
static void timerHandler (void *parm)
{
    ULONGLONG   msOffset = radTimeGetMSSinceEpoch ();
    int         rules;
    long long   netOffset;

    //  ... allow for timer latency
    if (ftpWork.msOffset == 0)
    {
        // first time through
        ftpWork.msOffset = msOffset;
        netOffset = 0;
    }
    else
    {
        netOffset = msOffset - ftpWork.msOffset;
        while (netOffset >= 60000LL)
        {
            netOffset -= 60000LL;
        }
    }

    while (ftpWork.msOffset < msOffset)
    {
        ftpWork.msOffset += 60000ULL;
    }

    radProcessTimerStart(ftpWork.timer, (ULONG)(60000LL - netOffset));


    //  ... process the ftp rules
    rules = ftpUtilsSendFiles(ftpWork.ftpId, ftpWork.wviewdir);

    if (rules > 0)
    {
        wvutilsLogEvent (PRI_STATUS, "FTP: %d rules processed", rules);
    }
    else if (rules < 0)
    {
        wvutilsLogEvent (PRI_MEDIUM, "FTP: ftpUtilsSendFiles failed!");
    }

    return;
}
Esempio n. 6
0
File: station.c Progetto: breu/wview
int stationPushDataToClients (WVIEWD_WORK *work)
{
    WVIEW_MSG_LOOP_DATA loop;

    if (!work->runningFlag)
    {
        return OK;
    }

    memcpy (&loop.loopData, &work->loopPkt, sizeof (loop.loopData));

    if (radMsgRouterMessageSend (WVIEW_MSG_TYPE_LOOP_DATA_SVC, &loop, sizeof(loop))
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "radMsgRouterMessageSend failed for loop transmit!");
        return ERROR;
    }

    radProcessTimerStart (work->pushTimer, work->pushInterval);
    return OK;
}
Esempio n. 7
0
static void timerHandler (void *parm)
{
    uint64_t    msOffset = radTimeGetMSSinceEpoch ();
    int64_t     netOffset;
    uint64_t    xoffset;

    //  ... allow for timer latency
    if (sshWork.msOffset == 0ULL)
    {
        // first time through
        sshWork.msOffset = msOffset;
        netOffset = 0LL;
    }
    else
    {
        netOffset = msOffset - sshWork.msOffset;
    }

    sshWork.msOffset += 60000ULL;               // ALWAYS 1 minute
    xoffset = sshWork.msOffset;

    // Cope with long scheduling delays or with the time being changed
    int32_t timerWait = (int32_t)(60000LL - netOffset);
    if ((timerWait <= 0) || (timerWait > 120000))
    {
        radMsgLog (PRI_HIGH, "wviewsshd: unusual wait %d; fixing it up", timerWait);
        // Keep the offset into the minute to keep updates aligned with the original alignment.
        uint64_t baseNow = (msOffset / 60000ULL) * 60000ULL;
        netOffset = 60000ULL;
        sshWork.msOffset = baseNow + netOffset + (sshWork.msOffset % 60000ULL);
        radMsgLog (PRI_HIGH, "wviewsshd: fixed offset is %llu", sshWork.msOffset);
    }

    radProcessTimerStart (sshWork.timer, (uint32_t)(60000LL - netOffset));

    //  ... process the ssh rules
    sshUtilsSendFiles (sshWork.sshId, sshWork.wviewdir);

    return;
}
Esempio n. 8
0
File: procmon.c Progetto: breu/wview
static void pollTimerHandler (void *parm)
{
    int                 i, mask = 0;
    WVIEW_MSG_POLL      poll;
    PMON_STIM           stim;

    // Set active process bits:
    for (i = 0; i < PMON_PROCESS_MAX; i ++)
    {
        if (procmonWork.process[i].timeout <= 0 ||
                radStatesGetState (procmonWork.process[i].stateMachine) != PMON_STATE_IDLE)
        {
            // Skip this guy
            continue;
        }

        mask = PMON_PROCESS_SET(mask,i);
        procmonWork.process[i].ticks = procmonWork.process[i].timeout;

        // Tickle the state machine
        memset (&stim, 0, sizeof(stim));
        stim.index = i;
        stim.type  = PMON_STIM_POLL;
        radStatesProcess (procmonWork.process[i].stateMachine, &stim);
    }

    poll.mask = mask;
    if (radMsgRouterMessageSend (WVIEW_MSG_TYPE_POLL, &poll, sizeof(poll))
            == ERROR)
    {
        radMsgLog (PRI_HIGH, "pollTimerHandler: radMsgRouterMessageSend failed!");
    }

    radProcessTimerStart (procmonWork.pollTimer, PMON_POLL_INTERVAL);
    return;
}
Esempio n. 9
0
File: cwop.c Progetto: 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);
}
Esempio n. 10
0
File: daemon.c Progetto: breu/wview
static int daemonStationInitComplete (void *eventData)
{
    struct tm           locTime;
    time_t              nowtime;
    ARCHIVE_PKT         newestRecord;

    if (eventData != 0)
    {
        // failed startup!
        radMsgLog (PRI_HIGH, "daemonStationInitComplete: station startup failed!");
        return ERROR;
    }

    if (!wviewdWork.runningFlag)
    {
        wviewdWork.runningFlag = TRUE;

        // set the positional data:
        if (stationGetPosition (&wviewdWork) == ERROR)
        {
            radMsgLog (PRI_HIGH, "daemonStationInitComplete: stationGetPosition failed!");
            emailAlertSend(ALERT_TYPE_STATION_READ);
            return ERROR;
        }

        // !!! the order of these calls is very important !!!

        // Initialize the HILOW database interface:
        computedDataInit (&wviewdWork);

        stormRainInit (wviewdWork.stationRainStormTrigger,
                       wviewdWork.stationRainStormIdleHours);

        computedDataClearInterval (&wviewdWork, 0, 0);

        // we know it just finished an initial sensor readings, it is a
        // REQUIREMENT of the stationInit API...
        daemonStationLoopComplete ();

        // do an initial update to propogate the initial readings
        // (so we have some data to start with)
        computedDataUpdate (&wviewdWork, NULL);

        // start the timers...
        stationStartArchiveTimerUniform (&wviewdWork);
        stationStartCDataTimerUniform (&wviewdWork);
        radProcessTimerStart (wviewdWork.pushTimer, 30000L);  // first run
        stationStartSyncTimerUniform (&wviewdWork, TRUE);     // first run

        radMsgLog (PRI_STATUS, "-- Station Init Complete --");

        // get the newest archive file record date/time
        wviewdWork.archiveDateTime = dbsqliteArchiveGetNewestTime(&newestRecord);
        if ((int)wviewdWork.archiveDateTime == ERROR)
        {
            wviewdWork.archiveDateTime = time(NULL);
            radMsgLog (PRI_STATUS, "no archive records found in database!");
        }
        else
        {
            radMsgLog (PRI_STATUS, "newest archive record: %4.4d-%2.2d-%2.2d %2.2d:%2.2d",
                       wvutilsGetYear(wviewdWork.archiveDateTime),
                       wvutilsGetMonth(wviewdWork.archiveDateTime),
                       wvutilsGetDay(wviewdWork.archiveDateTime),
                       wvutilsGetHour(wviewdWork.archiveDateTime),
                       wvutilsGetMin(wviewdWork.archiveDateTime));
        }

        // finally, answer all the WVIEW_RQST_TYPE_STATION_INFO requestors
        // so they can continue initialization - our data is ready:
        stationProcessInfoResponses(&wviewdWork);
    }

    return OK;
}
Esempio n. 11
0
File: procmon.c Progetto: 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);
}
Esempio n. 12
0
/*  ... the main entry point for the ssh process
*/
int main (int argc, char *argv[])
{
    void            (*alarmHandler)(int);
    STIM            stim;
    int             i;
    int             seconds;
    time_t          ntime;
    struct tm       locTime;
    int             offset, retVal;
    long            msOffset;
    FILE            *pidfile;
    int             runAsDaemon = TRUE;

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

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

    /*  ... initialize some system stuff first
    */
    retVal = sshSysInit (&sshWork);
    if (retVal == ERROR)
    {
        radMsgLogInit (PROC_NAME_SSH, FALSE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "ssh 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_SSH, TRUE, TRUE);
        radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!");
        radMsgLogExit ();
        exit (1);
    }


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

    sshWork.myPid = getpid ();
    pidfile = fopen (sshWork.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 (SSHDefaultSigHandler);
    radProcessSignalCatch (SIGALRM, alarmHandler);
    radProcessSignalRelease(SIGABRT);


    sshWork.timer = radTimerCreate (NULL, timerHandler, NULL);
    if (sshWork.timer == NULL)
    {
        radMsgLog (PRI_HIGH, "radTimerCreate failed - exiting");
        sshSysExit (&sshWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }

    //  ... initialize the ssh utilities
    retVal = sshUtilsInit (&sshWork.sshData);
    if (retVal != OK)
    {
        if (retVal == ERROR)
        {
            radMsgLog (PRI_HIGH, "sshUtilsInit failed - exiting");
        }
        radTimerDelete (sshWork.timer);
        sshSysExit (&sshWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    else
    {
        sshWork.sshId = &sshWork.sshData;
    }

    if (statusInit(sshWork.statusFile, sshStatusLabels) == ERROR)
    {
        radMsgLog (PRI_HIGH, "statusInit failed - exiting...");
        sshSysExit (&sshWork);
        radProcessExit ();
        radSystemExit (WVIEW_SYSTEM_ID);
        exit (1);
    }
    statusUpdate(STATUS_BOOTING);
    statusUpdateStat(SSH_STATS_RULES_DEFINED, 
                     radListGetNumberOfNodes(&sshWork.sshData.rules));

    //  ... start THE timer
    ntime = time (NULL);
    localtime_r (&ntime, &locTime);
    seconds = locTime.tm_sec - 15;          // start at 15 secs past

    /*  ... start the ssh timer to go off 1 min past the next archive record
    */
    offset = locTime.tm_min % 5;
    if (offset)
        offset = 6 - offset;
    else
        offset = 1;

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

    radMsgLog (PRI_HIGH,
               "SSH: starting updates in %d mins %d secs",
               ((seconds > 0) ? ((offset > 0) ? offset-1 : offset) : offset),
                       (seconds > 0) ? 60 - seconds : (-1) * seconds);

    msOffset = radTimeGetMSSinceEpoch () % 1000;
    msOffset -= 250;                        // land on 250 ms mark


    sshWork.msOffset = 0;
    radProcessTimerStart (sshWork.timer,
                          ((((offset * 60) - seconds) * 1000)) - msOffset);

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


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


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

    if (sshWork.sshId != NULL)
    {
        sshUtilsExit (sshWork.sshId);
    }
    radTimerDelete (sshWork.timer);
    sshSysExit (&sshWork);
    radProcessExit ();
    radSystemExit (WVIEW_SYSTEM_ID);
    exit (0);
}
Esempio n. 13
0
static void processNewArchiveRecord (HTML_WORK *work, WVIEW_MSG_ARCHIVE_NOTIFY *armsg)
{
    HISTORY_DATA        data;
    ARCHIVE_PKT         arcRecord;
    int                 currHour, currDay, currMonth, currYear;
    float               gmtOffsetHours;
    int                 startmin, starthour, startday, startmonth, startyear;
    int                 i, DSTFlag;
    int16_t             tempShort;
    time_t              ntime, baseTime;
    struct tm           locTime;
    int                 deltaArchiveIntervals;

    //  ... generate the mesonet file
    htmlgenMesonetFile (work->mgrId, armsg);

    //  ... check to see if a DST change has occured
    DSTFlag = wvutilsDetectDSTChange();
    if (DSTFlag != WVUTILS_DST_NO_CHANGE)
    {
        radMsgLog (PRI_STATUS, "DST change: updating astronomical times for new local time...");

        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

        //  ... update the sun times:
        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);

        // restart the generation timer as the change may leave it in limbo
        radProcessTimerStart (work->timer, 5000L);
    }

    baseTime = time (NULL);

    //  ... update our data by adding the new sample

    //// Interval change:

    //  ... determine time to start for last sample
    startmin    = wvutilsGetMin(armsg->dateTime);
    starthour   = wvutilsGetHour(armsg->dateTime);
    startday    = wvutilsGetDay(armsg->dateTime);
    startmonth  = wvutilsGetMonth(armsg->dateTime);
    startyear   = wvutilsGetYear(armsg->dateTime);

    currHour    = starthour;
    currDay     = startday;
    currMonth   = startmonth;
    currYear    = startyear;

    if (work->LastArchiveDateTime != 0)
    {
        // compute the number of archive intervals since the last good record
        deltaArchiveIntervals = armsg->dateTime - work->LastArchiveDateTime;
        deltaArchiveIntervals /= 60;
        if (deltaArchiveIntervals < work->archiveInterval)
        {
            // this is odd, report and bail out
            radMsgLog (PRI_MEDIUM, "processNewArchiveRecord: "
                                   "minutes since last archive record (%d) "
                                   "less than archive interval (%d) - "
                                   "ignoring record...",
                                   deltaArchiveIntervals,
                                   work->archiveInterval);
            return;
        }

        deltaArchiveIntervals /= work->archiveInterval;
    }
    else
    {
        deltaArchiveIntervals = 1;
    }

    work->LastArchiveDateTime = armsg->dateTime;

    if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                    work->archiveInterval,
                                    &data,
                                    armsg->dateTime,
                                    1)
        <= 0)
    {
        // populate history data with ARCHIVE_VALUE_NULL
        for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
        {
            data.values[i] = ARCHIVE_VALUE_NULL;
            data.samples[i] = 0;
        }
        radMsgLog (PRI_MEDIUM, "no data found for sample...");
    }

    wvutilsLogEvent (PRI_STATUS, "Adding %d minute sample for %4.4d-%2.2d-%2.2d %2.2d:%2.2d...", 
                     work->archiveInterval, startyear, startmonth, startday, starthour, startmin);

    //  ... set the archiveAvailable flag for generation...
    work->mgrId->newArchiveMask |= NEW_ARCHIVE_SAMPLE;

    // add the RX check value to the data here
    data.values[DATA_INDEX_rxCheckPercent] = armsg->rxPercent;

    htmlmgrAddSampleValue (work->mgrId, &data, deltaArchiveIntervals);
        
    // generate an ASCII entry in the day's browser file (if enabled)
    if (dbsqliteArchiveGetRecord(armsg->dateTime, &arcRecord) == OK)
    {
        arcrecGenerate(&arcRecord, work->mgrId->isMetricUnits);
    }


    //// Hour change?
    if (work->histLastHour != currHour)
    {
        // determine times to start for last hour:
        ntime = time (NULL);
        localtime_r (&ntime, &locTime);
        locTime.tm_sec   = 0;
        locTime.tm_min   = work->archiveInterval;
        locTime.tm_hour  = currHour;
        locTime.tm_mday  = currDay;
        locTime.tm_mon   = currMonth - 1;
        locTime.tm_year  = currYear - 1900;
        locTime.tm_isdst = -1;

        ntime = mktime (&locTime);
        ntime -= WV_SECONDS_IN_HOUR;
        localtime_r (&ntime, &locTime);

        starthour = locTime.tm_hour;

        if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                        work->archiveInterval,
                                        &data,
                                        ntime,
                                        WV_SECONDS_IN_HOUR/SECONDS_IN_INTERVAL(work->archiveInterval))
            <= 0)
        {
            // populate history data with ARCHIVE_VALUE_NULL
            for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
            {
                data.values[i] = ARCHIVE_VALUE_NULL;
                data.samples[i] = 0;
            }
            radMsgLog (PRI_MEDIUM, "no data found for last hour...");
        }

        wvutilsLogEvent (PRI_STATUS, "Adding hour sample...");

        //  ... set the archiveAvailable flag for generation...
        work->mgrId->newArchiveMask |= NEW_ARCHIVE_HOUR;

        htmlmgrAddHourValue (work->mgrId, &data);

        work->histLastHour = currHour;
    }

    //// Day change?
    if (work->histLastDay != currDay)
    {
        // determine times to start for last day:
        // normalize packed time:
        ntime = time (NULL);
        localtime_r (&ntime, &locTime);
        locTime.tm_sec   = 0;
        locTime.tm_min   = work->archiveInterval;
        locTime.tm_hour  = 0;
        locTime.tm_mday  = currDay;
        locTime.tm_mon   = currMonth - 1;
        locTime.tm_year  = currYear - 1900;
        locTime.tm_isdst = -1;
#ifdef HAVE_TM_GMTOFF
        gmtOffsetHours = locTime.tm_gmtoff/(60.0*60.0);
#else   
        gmtOffsetHours = gmtoffset()/(60.0*60.0);
#endif

        ntime = mktime (&locTime);
        ntime -= WV_SECONDS_IN_DAY;
        localtime_r (&ntime, &locTime);

        if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                        work->archiveInterval,
                                        &data,
                                        ntime,
                                        WV_SECONDS_IN_DAY/SECONDS_IN_INTERVAL(work->archiveInterval))
            <= 0)
        {
            // populate history data with ARCHIVE_VALUE_NULL
            for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
            {
                data.values[i] = ARCHIVE_VALUE_NULL;
                data.samples[i] = 0;
            }
            radMsgLog (PRI_MEDIUM, "no data found for last day...");
        }
        else
        {
            // Add a day history record:
            wvutilsLogEvent(PRI_STATUS, "Storing day history for %s", ctime(&ntime));
            dbsqliteHistoryInsertDay(&data);
        }

        //  ... set the archiveAvailable flag for generation...
        work->mgrId->newArchiveMask |= NEW_ARCHIVE_DAY;

        wvutilsLogEvent(PRI_STATUS, "Adding day sample...");
        htmlmgrAddDayValue (work->mgrId, &data);

        work->histLastDay = currDay;

        //  Start the timeout to do NOAA updates:
        radProcessTimerStart(work->noaaTimer, HTML_NOAA_UPDATE_DELAY);

        //  ... update the sun times
        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);

    }

    return;
}
Esempio n. 14
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;
}