void wmr918GetReadings (WVIEWD_WORK *work) { WMR918_IF_DATA* ifWorkData = (WMR918_IF_DATA*)work->stationData; // populate the LOOP structure: ifWorkData->wmr918Readings = wmr918Work.sensorData; storeLoopPkt (work, &work->loopPkt, &ifWorkData->wmr918Readings); // indicate the LOOP packet is done radProcessEventsSend (NULL, STATION_LOOP_COMPLETE_EVENT, 0); }
// station-supplied function to indicate sensor readings should be performed - // should populate 'work' struct: loopPkt (see datadefs.h for minimum field reqs) // -- Can Be Asynchronous -- // // - indicate readings are complete by sending the STATION_LOOP_COMPLETE_EVENT // event to this process (radProcessEventsSend (NULL, STATION_LOOP_COMPLETE_EVENT, 0)) // // Returns: OK or ERROR // int stationGetReadings (WVIEWD_WORK *work) { // we will do this synchronously... // populate the LOOP structure (with dummy data) storeLoopPkt (work, &work->loopPkt); // indicate we are done radProcessEventsSend (NULL, STATION_LOOP_COMPLETE_EVENT, 0); return OK; }
void wh1080GetReadings (WVIEWD_WORK *work) { WH1080_IF_DATA* ifWorkData = (WH1080_IF_DATA*)work->stationData; if (readStationData(work) == OK) { // populate the LOOP structure: ifWorkData->wh1080Readings = wh1080Work.sensorData; storeLoopPkt (work, &work->loopPkt, &ifWorkData->wh1080Readings); // indicate the LOOP packet is done radProcessEventsSend (NULL, STATION_LOOP_COMPLETE_EVENT, 0); } }
// station-supplied function to indicate sensor readings should be performed - // should populate 'work' struct: loopPkt (see datadefs.h for minimum field reqs) // -- Can Be Asynchronous -- // // - indicate readings are complete by sending the STATION_LOOP_COMPLETE_EVENT // event to this process (radProcessEventsSend (NULL, STATION_LOOP_COMPLETE_EVENT, 0)) // // Returns: OK or ERROR // int stationGetReadings (WVIEWD_WORK *work) { // we will do this synchronously... // get readings from station if (virtualProtocolGetReadings(work, &virtualWorkData.virtualReadings) == OK) { // populate the LOOP structure storeLoopPkt(&work->loopPkt, &virtualWorkData); // indicate we are done radProcessEventsSend(NULL, STATION_LOOP_COMPLETE_EVENT, 0); } return OK; }
int wmr918Init (WVIEWD_WORK *work) { WMR918_IF_DATA* ifWorkData = (WMR918_IF_DATA*)work->stationData; fd_set rfds; struct timeval tv; int i, length, retVal; time_t nowTime = time(NULL) - (WV_SECONDS_IN_HOUR/(60/WMR918_RAIN_RATE_PERIOD)); ARCHIVE_PKT recordStore; char outString[128]; memset (&wmr918Work, 0, sizeof(wmr918Work)); // Create the rain accumulator (WMR918_RAIN_RATE_PERIOD minute age) // so we can compute rain rate: ifWorkData->rainRateAccumulator = sensorAccumInit(WMR918_RAIN_RATE_PERIOD); // Populate the accumulator with the last WMR918_RAIN_RATE_PERIOD minutes: while ((nowTime = dbsqliteArchiveGetNextRecord(nowTime, &recordStore)) != ERROR) { sensorAccumAddSample(ifWorkData->rainRateAccumulator, recordStore.dateTime, recordStore.value[DATA_INDEX_rain]); } radMsgLog (PRI_MEDIUM, "wmr918Init: waiting for first sensor packets (this may take some time):"); while ((wmr918Work.dataRXMask != WMR918_SENSOR_ALL) && (! work->exiting)) { // Log what we are waiting for: length = 0; for (i = 0; i < 4; i ++) { if (! (wmr918Work.dataRXMask & (1 << i))) { length += sprintf(&outString[length], "%s ", WMRSensorNames[i]); } } radMsgLog (PRI_MEDIUM, "wmr918Init: waiting for sensors: %s", outString); tv.tv_sec = 2; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(work->medium.fd, &rfds); if (select (work->medium.fd + 1, &rfds, NULL, NULL, &tv) > 0) { retVal = readStationData (work); switch (retVal) { case WMR918GROUP0: radMsgLog (PRI_MEDIUM, "received WIND packet..."); break; case WMR918GROUP1: radMsgLog (PRI_MEDIUM, "received RAIN packet..."); break; case WMR918GROUP2: radMsgLog (PRI_MEDIUM, "received EXTRA TEMP packet..."); break; case WMR918GROUP3: radMsgLog (PRI_MEDIUM, "received OUT TEMP packet..."); break; case WMR918GROUP4: radMsgLog (PRI_MEDIUM, "received POOL TEMP packet..."); break; case WMR918GROUP5: case WMR918GROUP6: radMsgLog (PRI_MEDIUM, "received IN TEMP packet..."); break; default: break; } } } if (! work->exiting) { radMsgLog (PRI_MEDIUM, "wmr918Init: first sensor packets received."); } // populate the LOOP structure: ifWorkData->wmr918Readings = wmr918Work.sensorData; storeLoopPkt (work, &work->loopPkt, &ifWorkData->wmr918Readings); // 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; }
// 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; }
// 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; }
// 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 minutes; memset (&simWorkData, 0, sizeof(simWorkData)); // save the archive indication callback (we should never need it) ArchiveIndicator = archiveIndication; // set our work data pointer work->stationData = &simWorkData; // set the Archive Generation flag to indicate the Simulator DOES NOT // generate them work->stationGeneratesArchives = FALSE; // initialize the medium abstraction based on user configuration // we won't really open a serial channel... work->medium.type = MEDIUM_TYPE_NONE; // grab the station configuration now if (stationGetConfigValueInt (work, STATION_PARM_ELEVATION, &simWorkData.elevation) == ERROR) { radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt ELEV failed!"); (*(work->medium.exit)) (&work->medium); return ERROR; } if (stationGetConfigValueFloat (work, STATION_PARM_LATITUDE, &simWorkData.latitude) == ERROR) { radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt LAT failed!"); (*(work->medium.exit)) (&work->medium); return ERROR; } if (stationGetConfigValueFloat (work, STATION_PARM_LONGITUDE, &simWorkData.longitude) == ERROR) { radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt LONG failed!"); (*(work->medium.exit)) (&work->medium); return ERROR; } if (stationGetConfigValueInt (work, STATION_PARM_ARC_INTERVAL, &simWorkData.archiveInterval) == ERROR) { radMsgLog (PRI_HIGH, "stationInit: stationGetConfigValueInt ARCINT failed!"); (*(work->medium.exit)) (&work->medium); return ERROR; } // set the work archive interval now work->archiveInterval = simWorkData.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..."); return ERROR; } else { radMsgLog (PRI_STATUS, "station archive interval: %d minutes", work->archiveInterval); } // initialize the station interface // nothing to do here... radMsgLog (PRI_STATUS, "Starting station interface: Simulator"); // do the initial GetReadings now // populate the LOOP structure storeLoopPkt (work, &work->loopPkt); // compute the data generation period minutes = 360 * PERIOD_FACTOR; minutes *= (work->cdataInterval/1000); minutes /= 60; radMsgLog (PRI_STATUS, "Simulator station opened: %d minute data generation period...", minutes); // we can indicate successful completion here! radProcessEventsSend (NULL, STATION_INIT_COMPLETE_EVENT, 0); return OK; }
int wh1080Init (WVIEWD_WORK *work) { WH1080_IF_DATA* ifWorkData = (WH1080_IF_DATA*)work->stationData; fd_set rfds; struct timeval tv; int ret; time_t nowTime = time(NULL) - (WV_SECONDS_IN_HOUR/(60/WH1080_RAIN_RATE_PERIOD)); ARCHIVE_PKT recordStore; unsigned char controlBlock[WH1080_BUFFER_CHUNK]; memset (&wh1080Work, 0, sizeof(wh1080Work)); // Create the rain accumulator (WH1080_RAIN_RATE_PERIOD minute age) // so we can compute rain rate: ifWorkData->rainRateAccumulator = sensorAccumInit(WH1080_RAIN_RATE_PERIOD); // Populate the accumulator with the last WH1080_RAIN_RATE_PERIOD minutes: while ((nowTime = dbsqliteArchiveGetNextRecord(nowTime, &recordStore)) != ERROR) { sensorAccumAddSample(ifWorkData->rainRateAccumulator, recordStore.dateTime, recordStore.value[DATA_INDEX_rain]); } if ((*(work->medium.usbhidInit))(&work->medium) != OK) { return ERROR; } // Set the station to log data once per minute: while ((!work->exiting) && (readFixedBlock(work, controlBlock) != OK)) { radMsgLog (PRI_HIGH, "WH1080: Initial fixed block read failed"); (*(work->medium.usbhidExit))(&work->medium); radUtilsSleep(5000); (*(work->medium.usbhidInit))(&work->medium); radMsgLog (PRI_HIGH, "WH1080: Retrying initial fixed block read"); } // For some reason the WH1080 wants the IF closed between a read and a write: (*(work->medium.usbhidExit))(&work->medium); if (work->exiting) { return ERROR; } controlBlock[WH1080_SAMPLING_INTERVAL] = 1; (*(work->medium.usbhidInit))(&work->medium); if (writeFixedBlock(work, controlBlock) == ERROR) { (*(work->medium.usbhidExit))(&work->medium); return ERROR; } radUtilsSleep(2000); (*(work->medium.usbhidExit))(&work->medium); radUtilsSleep(1000); wh1080Work.lastRecord = -1; // populate the LOOP structure: radMsgLog (PRI_HIGH, "Waiting for the next weather record to be ready " "in the console to populate initial wview sensor readings " "(this could take some time);"); radMsgLog (PRI_HIGH, "While waiting be sure you are receiving all sensors on the console;"); radMsgLog (PRI_HIGH, "if not, you may need to relocate the sensors or the console."); while ((!work->exiting) && (readStationData(work) != OK)) { radUtilsSleep(1000); } if (work->exiting) { return ERROR; } ifWorkData->wh1080Readings = wh1080Work.sensorData; storeLoopPkt (work, &work->loopPkt, &ifWorkData->wh1080Readings); // 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; }