// Returns: // OK - if new record retrieved // ERROR - if there was an interface error // ERROR_ABORT - if there is no new record (WH1080 generates new records at // best once a minute) static int readStationData (WVIEWD_WORK *work) { WH1080_IF_DATA* ifWorkData = (WH1080_IF_DATA*)work->stationData; int currentPosition, readPosition, index, retVal; if ((*(work->medium.usbhidInit))(&work->medium) != OK) { return ERROR; } // Read the WH1080 fixed block: retVal = readFixedBlock(work, &wh1080Work.controlBlock[0]); if (retVal == ERROR_ABORT) { // Try again later (bad magic number): (*(work->medium.usbhidExit))(&work->medium); return ERROR_ABORT; } else if (retVal == ERROR) { // USB interface error: (*(work->medium.usbhidExit))(&work->medium); return ERROR; } // Get the current record position; the WH1080 reports the record it is // building, thus if it changes we need the prior just finished record: currentPosition = (int)getUSHORT(&wh1080Work.controlBlock[WH1080_CURRENT_POS]); // Make sure the index is aligned on 16-byte boundary: if ((currentPosition % 16) != 0) { // bogus, try again later: (*(work->medium.usbhidExit))(&work->medium); return ERROR_ABORT; } // Is this the first time? if (wh1080Work.lastRecord == -1) { // Yes. wh1080Work.lastRecord = currentPosition; (*(work->medium.usbhidExit))(&work->medium); return ERROR_ABORT; } // Is there a new record? if (currentPosition == wh1080Work.lastRecord) { // No, wait till it is finished. (*(work->medium.usbhidExit))(&work->medium); return ERROR_ABORT; } // Read last record that is now complete: if (readBlock(work, wh1080Work.lastRecord, &wh1080Work.recordBlock[0]) == ERROR) { radMsgLog (PRI_HIGH, "WH1080: read data block at index %d failed!", wh1080Work.lastRecord); (*(work->medium.usbhidExit))(&work->medium); return ERROR; } (*(work->medium.usbhidExit))(&work->medium); readPosition = wh1080Work.lastRecord; wh1080Work.lastRecord = currentPosition; //radMsgLogData(wh1080Work.recordBlock, 32); // Is the record valid? Check for unpopulated record or no sensor data // received status bit: if ((wh1080Work.recordBlock[WH1080_STATUS] & 0x40) != 0) { // No! radMsgLog (PRI_HIGH, "WH1080: data block at index %d has bad status, ignoring the record", readPosition); return ERROR_ABORT; } // Parse the data received: for (index = 0; index < WH1080_NUM_SENSORS; index ++) { if (decodeSensor(&wh1080Work.recordBlock[decodeVals[index].pos], decodeVals[index].ws_type, decodeVals[index].scale, decodeVals[index].var) != OK) { // Bad sensor data, abort this cycle: radMsgLog (PRI_HIGH, "WH1080: data block at index %d has bad sensor value, ignoring the record", readPosition); return ERROR_ABORT; } } // Convert to Imperial units: wh1080Work.sensorData.intemp = wvutilsConvertCToF(wh1080Work.sensorData.intemp); wh1080Work.sensorData.outtemp = wvutilsConvertCToF(wh1080Work.sensorData.outtemp); wh1080Work.sensorData.pressure = wvutilsConvertHPAToINHG(wh1080Work.sensorData.pressure); wh1080Work.sensorData.windAvgSpeed = wvutilsConvertMPSToMPH(wh1080Work.sensorData.windAvgSpeed); wh1080Work.sensorData.windGustSpeed = wvutilsConvertMPSToMPH(wh1080Work.sensorData.windGustSpeed); wh1080Work.sensorData.rain = wvutilsConvertMMToIN(wh1080Work.sensorData.rain); return OK; }
// Returns: // OK - if new record retrieved // ERROR - if there was an interface error // ERROR_ABORT - if there is no new record (WH1080 generates new records at // best once a minute) static int readStationData (WVIEWD_WORK *work) { WH1080_IF_DATA* ifWorkData = (WH1080_IF_DATA*)work->stationData; int currentPosition, index; if ((*(work->medium.usbhidInit))(&work->medium) != OK) { return ERROR; } // Read the WH1080 fixed block: if (readFixedBlock(work, &wh1080Work.controlBlock[0]) == ERROR) { (*(work->medium.usbhidExit))(&work->medium); return ERROR; } // Get the current record position; the WH1080 reports the record it is // building, thus if it changes we need the prior just finished record: currentPosition = (int)getUSHORT(&wh1080Work.controlBlock[WH1080_CURRENT_POS]); currentPosition -= WH1080_BUFFER_RECORD; if (currentPosition < WH1080_BUFFER_START) { // wrap back around to the end of the memory block: currentPosition = WH1080_BUFFER_END; } // Is there a new record? if (currentPosition == wh1080Work.lastRecord) { // No! (*(work->medium.usbhidExit))(&work->medium); return ERROR_ABORT; } // Read current and next record on first read on even position if (readBlock(work, currentPosition, &wh1080Work.recordBlock[0]) == ERROR) { radMsgLog (PRI_HIGH, "WH1080: read data block at index %d failed!", currentPosition); (*(work->medium.usbhidExit))(&work->medium); return ERROR; } (*(work->medium.usbhidExit))(&work->medium); wh1080Work.lastRecord = currentPosition; //radMsgLogData(wh1080Work.recordBlock, 32); // Is the record valid? Check for unpopulated record or no sensor data // received status bit: if (((wh1080Work.recordBlock[0] != 1)) || ((wh1080Work.recordBlock[WH1080_STATUS] & 0x40) != 0)) { // No! return ERROR_ABORT; } // Parse the data received: for (index = 0; index < WH1080_NUM_SENSORS; index ++) { if (decodeSensor(&wh1080Work.recordBlock[decodeVals[index].pos], decodeVals[index].ws_type, decodeVals[index].scale, decodeVals[index].var) != OK) { // Bad sensor data, abort this cycle: return ERROR_ABORT; } } // Convert to Imperial units: wh1080Work.sensorData.intemp = wvutilsConvertCToF(wh1080Work.sensorData.intemp); wh1080Work.sensorData.outtemp = wvutilsConvertCToF(wh1080Work.sensorData.outtemp); wh1080Work.sensorData.pressure = wvutilsConvertHPAToINHG(wh1080Work.sensorData.pressure); wh1080Work.sensorData.windAvgSpeed = wvutilsConvertMPSToMPH(wh1080Work.sensorData.windAvgSpeed); wh1080Work.sensorData.windGustSpeed = wvutilsConvertMPSToMPH(wh1080Work.sensorData.windGustSpeed); wh1080Work.sensorData.rain = wvutilsConvertMMToIN(wh1080Work.sensorData.rain); return OK; }