Exemple #1
0
static int RestoreConnection(WVIEWD_WORK *work)
{
    if (ethernetMediumInit (&work->medium, work->stationHost, work->stationPort)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "RestoreConnection: ethernet MediumInit failed");
        return ERROR_ABORT;
    }

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

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

    return OK;
}
Exemple #2
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;
    STIM            stim;

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

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

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

    // set the Archive Generation flag to indicate the WS-2300 DOES NOT
    // generate them
    work->stationGeneratesArchives = FALSE;

    // initialize the medium abstraction based on user configuration
    if (!strcmp (work->stationInterface, "serial"))
    {
        if (serialMediumInit (&work->medium, serialPortConfig, O_RDWR | O_NOCTTY | O_NDELAY) == ERROR)
        {
            radMsgLog (PRI_HIGH, "stationInit: serial MediumInit failed");
            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;
    }

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

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

    // now initialize the state machine
    ws2300WorkData.stateMachine = radStatesInit (work);
    if (ws2300WorkData.stateMachine == NULL)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesInit failed");
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }

    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_STARTPROC,
                             wsStartProcState)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_RUN,
                             wsRunState)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_ADRS0_ACK,
                             wsAdrs0State)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_ADRS1_ACK,
                             wsAdrs1State)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_ADRS2_ACK,
                             wsAdrs2State)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_ADRS3_ACK,
                             wsAdrs3State)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_NUMBYTES_ACK,
                             wsNumBytesState)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }
    if (radStatesAddHandler (ws2300WorkData.stateMachine, 
                             WS_STATE_ERROR,
                             wsErrorState)
        == ERROR)
    {
        radMsgLog (PRI_HIGH, "stationInit: radStatesAddHandler failed");
        radStatesExit (ws2300WorkData.stateMachine);
        (*(work->medium.exit)) (&work->medium);
        return ERROR;
    }

    radStatesSetState (ws2300WorkData.stateMachine, WS_STATE_STARTPROC);

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

    // dummy up a stimulus to get the state machine running
    stim.type = STIM_DUMMY;
    radStatesProcess (ws2300WorkData.stateMachine, &stim);

    return OK;
}
Exemple #3
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;
}
Exemple #4
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;
    ARCHIVE_PKT     recordStore;
    time_t          nowTime;

    memset (&twiWorkData, 0, sizeof(twiWorkData));
    pwviewWork = work;
    twiWorkData.baudrate = B19200;

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

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

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

    // initialize the medium abstraction based on user configuration
    if (!strcmp (work->stationInterface, "serial"))
    {
        if (serialMediumInit (&work->medium, serialPortConfig, O_RDWR | O_NOCTTY | O_NDELAY) == ERROR)
        {
            radMsgLog (PRI_HIGH, "stationInit: serial MediumInit failed");
            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;
    }

    // Autobaud the station now:
    twiWorkData.baudrate = twiConfig(work);
    if (twiWorkData.baudrate <= 0)
    {
        radMsgLog (PRI_HIGH, "TWI: twiProtocolInit: autobaud failed!");
        return ERROR;
    }

    radMsgLog (PRI_STATUS, "TWI: autobaud = %d", twiWorkData.baudrate);

    // Reconfigure the serial port here to ensure consistency:
    serialPortConfig(work->medium.fd);
    tcflush (work->medium.fd, TCIFLUSH);
    tcflush (work->medium.fd, TCOFLUSH);

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

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

    // set the work archive interval now
    work->archiveInterval = twiWorkData.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);
    }

    twiWorkData.totalRain = 0;

   // Create the rain accumulator (TWI_RAIN_RATE_PERIOD minute age)
    // so we can compute rain rate:
    twiWorkData.rainRateAccumulator = sensorAccumInit(TWI_RAIN_RATE_PERIOD);

    // Populate the accumulator with the last TWI_RAIN_RATE_PERIOD minutes:
    nowTime = time(NULL) - (WV_SECONDS_IN_HOUR/(60/TWI_RAIN_RATE_PERIOD));
    while ((nowTime = dbsqliteArchiveGetNextRecord(nowTime, &recordStore)) != ERROR)
    {
        sensorAccumAddSample(twiWorkData.rainRateAccumulator,
                             recordStore.dateTime,
                             recordStore.value[DATA_INDEX_rain]);
    }

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

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

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


    // Initialize the 12-hour temp accumulator:
    twi12HourTempAvg = sensorAccumInit(60 * 12);

    // Load data for the last 12 hours:
    nowTime = time(NULL) - (WV_SECONDS_IN_HOUR * 12);
    while ((nowTime = dbsqliteArchiveGetNextRecord(nowTime, &recordStore)) != ERROR)
    {
        sensorAccumAddSample(twi12HourTempAvg, 
                             recordStore.dateTime, 
                             recordStore.value[DATA_INDEX_outTemp]);
    }

    // populate the LOOP structure
    storeLoopPkt (work, &work->loopPkt, &twiWorkData.twiReadings);

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