#include "hidwh1080rptparser.h" WH1080ReportParser::WH1080ReportParser() { chunkStart = 0; readingBlockZero = true; for (uint8_t i = 0; i < sizeof(WH1080_REPORT); i++) { report[i] = pgm_read_byte(&WH1080_REPORT[i]); } memset(lastChunk, 0, WH1080_BUFFER_CHUNK); lastMillis = millis(); startDelay = 1000 + millis(); } void WH1080ReportParser::SetReadingBlock(uint8_t high, uint8_t low) { report[1] = high; report[2] = low; report[5] = high; report[6] = low; readingBlockZero = false; chunkStart = 0; } void WH1080ReportParser::SetReadingZero() { report[1] = 0; report[2] = 0; report[5] = 0; report[6] = 0; readingBlockZero = true; chunkStart = 0; } void WH1080ReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) { // See http://www.jim-easterbrook.me.uk/weather/mm/ if ((chunkStart + len) >= WH1080_BUFFER_CHUNK) { memcpy(chunk + chunkStart, buf, WH1080_BUFFER_CHUNK - chunkStart); chunkStart = 0; if (readingBlockZero) { SetReadingBlock(chunk[WH1080_CURRENT_POS + 1], chunk[WH1080_CURRENT_POS]); startDelay = millis() + 250; } else { if (memcmp(chunk, lastChunk, WH1080_BUFFER_CHUNK) != 0) { memcpy(lastChunk, chunk, WH1080_BUFFER_CHUNK); // wake up XBee /* digitalWrite(2, LOW); delay(1000); */ Serial.print("{\"period\":"); Serial.print(millis() - lastMillis); lastMillis = millis(); Serial.print(",\"delay\":"); Serial.print(chunk[WH1080_DELAY]); if (chunk[WH1080_HUMIDITY_IN] != 0xFF) { Serial.print(",\"in_humidity\":"); Serial.print(chunk[WH1080_HUMIDITY_IN]); } if (!((chunk[WH1080_TEMPERATURE_IN] == 0xFF) && (chunk[WH1080_TEMPERATURE_IN + 1] == 0xFF))) { Serial.print(",\"in_temp\":"); Serial.print((((chunk[WH1080_TEMPERATURE_IN+1] & 0x7f) << 8) + chunk[WH1080_TEMPERATURE_IN]) * ((chunk[WH1080_TEMPERATURE_IN+1] & 0x80) ? -0.1 : 0.1)); } if (chunk[WH1080_HUMIDITY_OUT] != 0xFF) { Serial.print(",\"out_humidity\":"); Serial.print(chunk[WH1080_HUMIDITY_OUT]); } if (!((chunk[WH1080_TEMPERATURE_OUT] == 0xFF) && (chunk[WH1080_TEMPERATURE_OUT + 1] == 0xFF))) { Serial.print(",\"out_temp\":"); Serial.print((((chunk[WH1080_TEMPERATURE_OUT+1] & 0x7f) << 8) + chunk[WH1080_TEMPERATURE_OUT]) * ((chunk[WH1080_TEMPERATURE_OUT+1] & 0x80) ? -0.1 : 0.1)); } if (!((chunk[WH1080_ABS_PRESSURE] == 0xFF) && (chunk[WH1080_ABS_PRESSURE + 1] == 0xFF))) { Serial.print(",\"pressure\":"); Serial.print(((chunk[WH1080_ABS_PRESSURE+1] << 8) + chunk[WH1080_ABS_PRESSURE]) * 0.1); } if (!((chunk[WH1080_WIND_AVE] == 0xFF) && ((chunk[WH1080_WIND_GUST + 1] & 0x0F) == 0x0F))) { Serial.print(",\"wind_speed\":"); Serial.print((chunk[WH1080_WIND_AVE] + ((chunk[WH1080_WIND_GUST+1] & 0x0f) << 8)) * 0.1); } if (!((chunk[WH1080_WIND_GUST] == 0xFF) && ((chunk[WH1080_WIND_GUST + 1] & 0xF0) == 0xF0))) { Serial.print(",\"wind_gust\":"); Serial.print((chunk[WH1080_WIND_GUST] + ((chunk[WH1080_WIND_GUST+1] & 0xf0) << 4)) * 0.1); } if (chunk[WH1080_WIND_DIR] != 0xFF) { Serial.print(",\"wind_dir\":"); Serial.print(chunk[WH1080_WIND_DIR] * 22.5); } if (!((chunk[WH1080_RAIN] == 0xFF) && (chunk[WH1080_RAIN + 1] == 0xFF))) { Serial.print(",\"rain\":"); Serial.print(((chunk[WH1080_RAIN+1] << 8) + chunk[WH1080_RAIN]) * 0.3); // TODO: check overflow bit } Serial.print(",\"status\":"); Serial.print(chunk[WH1080_STATUS]); Serial.println("}"); /* delay(5000); digitalWrite(2, HIGH); // put XBee to sleep */ } SetReadingZero(); startDelay = millis() + 5000; } } else { memcpy(chunk + chunkStart, buf, len); chunkStart += len; } }